type annotation vs working code

dn PythonList at DancesWithMice.info
Sat Sep 30 16:04:05 EDT 2023


On 01/10/2023 08.00, Karsten Hilbert via Python-list wrote:
> A type annotation isn't supposed to change what code does,
> or so I thought:
> 
> #------------------------------------------------------------
> class Borg:
> 	_instances:dict = {}
> 
> 	def __new__(cls, *args, **kargs):
> 		# look up subclass instance cache
> 		if Borg._instances.get(cls) is None:
> 			Borg._instances[cls] = object.__new__(cls)
> 		return Borg._instances[cls]
> 
> 
> class WorkingSingleton(Borg):
> 
> 	def __init__(self):
> 		print(self.__class__.__name__, ':')
> 		try:
> 			self.already_initialized
> 			print('already initialized')
> 			return
> 
> 		except AttributeError:
> 			print('initializing')
> 
> 		self.already_initialized = True
> 		self.special_value = 42
> 
> 
> class FailingSingleton(Borg):
> 
> 	def __init__(self):
> 		print(self.__class__.__name__, ':')
> 		try:
> 			self.already_initialized:bool
> 			print('already initialized')
> 			return
> 
> 		except AttributeError:
> 			print('initializing')
> 
> 		self.already_initialized = True
> 		self.special_value = 42
> 
> s = WorkingSingleton()
> print(s.special_value)
> 
> s = FailingSingleton()
> print(s.special_value)
> 
> #------------------------------------------------------------
> 
> Notice how Working* and Failing differ in the type annotation
> of self.already_initialized only.
> 
> Output:
> 
> 	WorkingSingleton :
> 	initializing
> 	42
> 
> 	FailingSingleton :
> 	already initialized				<====================== Huh ?
> 	Traceback (most recent call last):
> 	  File "/home/ncq/Projekte/gm/git/gnumed/gnumed/client/testing/test-singleton.py", line 48, in <module>
> 	    print(s.special_value)
> 	          ^^^^^^^^^^^^^^^
> 	AttributeError: 'FailingSingleton' object has no attribute 'special_value'
> 
> 
> Where's the error in my thinking (or code) ?

What is your thinking?
Specifically, what is the purpose of testing self.already_initialized?

Isn't it generally regarded as 'best practice' to declare (and define a 
value for) all attributes in __init__()? (or equivalent) In which case, 
it will (presumably) be defined as False; and the try-except reworded to 
an if-else.

Alternately, how about using hasattr()? eg

if hasattr( self.already_initialized, 'attribute_name' ):
   # attribute is defined, etc


As the code current stands, the:

         try:
             self.already_initialized

line is flagged by the assorted linters, etc, in my PyCharm as:

Statement seems to have no effect.
Unresolved attribute reference 'already_initialized' for class 
'WorkingSingleton'.

but:

             self.already_initialized:bool

passes without comment (see @Mats' response).


Question: is it a legal expression (without the typing)?

-- 
Regards,
=dn


More information about the Python-list mailing list