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

Reply via email to