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
--
https://mail.python.org/mailman/listinfo/python-list