----------------------------------------------------------------------------------
@MSGID:
<mailman.372.1696102506.23016.python-list@python.org> 2827d2db
@REPLY:
<d5e8dbff-8b43-4867-10bb-76ab6f6dbaf2@wichmann.us> d518f851
@REPLYADDR Mats Wichmann <mats@wichmann.us>
@REPLYTO 2:5075/128 Mats Wichmann
@CHRS: CP866 2
@RFC: 1 0
@RFC-Message-ID:
<mailman.372.1696102506.23016.python-list@python.org>
@RFC-References: <ZRhwWN29i3mskxEL@hermes.hilbert.loc>
<d5e8dbff-8b43-4867-10bb-76ab6f6dbaf2@wichmann.us>
@TZUTC: -0600
@PID: Mozilla/5.0 (X11; Linux x86_64; rv:102.0)
Gecko/20100101 Thunderbird/102.15.1
@TID: FIDOGATE-5.12-ge4e8b94
On 9/30/23 13: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.
What happens here is in the second case, the line is just recorded as a
variable annotation, and is not evaluated as a reference, as you`re
expecting to happen, so it just goes right to the print call without
raising the exception. You could change your initializer like this:
def __init__(self):
print(self.__class__.__name__, `:`)
self.already_initialized: bool
try:
self.already_initialized
print(`already initialized`)
return
The syntax description is here:
https://peps.python.org/pep-0526/#global-and-local-variable-annotations
--- Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
Thunderbird/102.15.1
* Origin: usenet.network (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