----------------------------------------------------------------------------------
@MSGID:
<mailman.373.1696104258.23016.python-list@python.org> 4cf5710e
@REPLY:
<ecc36615-1844-455f-b701-2bd41d98e9e1@DancesWithMice.info> ba82e524
@REPLYADDR dn <PythonList@DancesWithMice.info>
@REPLYTO 2:5075/128 dn
@CHRS: CP866 2
@RFC: 1 0
@RFC-Message-ID:
<mailman.373.1696104258.23016.python-list@python.org>
@RFC-References: <ZRhwWN29i3mskxEL@hermes.hilbert.loc>
<ecc36615-1844-455f-b701-2bd41d98e9e1@DancesWithMice.info>
@TZUTC: 1300
@PID: Mozilla Thunderbird
@TID: FIDOGATE-5.12-ge4e8b94
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
> 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
--- Mozilla Thunderbird
* Origin: DWM (2:5075/128)
SEEN-BY: 50/109 301/1 467/888 4500/1 5000/111
5001/100 5005/49 5020/715 830
SEEN-BY: 5020/848 1042 4441 12000 5030/49 1081
5054/8 5061/133 5075/128
SEEN-BY: 5080/102 5083/1 444
@PATH: 5075/128 5020/1042 4441