Re: Using __new__
On 18/02/24 13:21, Jonathan Gossage wrote: The problem is that if you are dealing with a library class, you may have times when the superclass is 'object' while at other times, with a different inheritance hierarchy, the superclass may need arguments. My thought is that the object class __new__ method should not choke on arguments, just ignore them. All true. So, what you're looking for is one mechanism to rule them all? Not going to happen: for exactly the reasons you've stated. If you really want to get right 'down into the weeds' with a __new__() constructor, then you're well into customisation-territory. I think it would be 'going nuts' but... If it 'absolutely, positively, ...' then perhaps introspect the super-class and modify the call based-upon whether it is 'something' or "object"? (in similar fashion to the singleton's if-statement attempting to make sure it is unique) - perhaps someone knows a better/proper way to do this? Suggested research: custom classes, ABCs, and meta-classes... See also recent improvements to Python which have made it easier for sub-classes (and Descriptors - __set_name__() ) to identify who/how/where to 'phone home', in case (also) applicable... When I talk about 'object', I am talking about the ultimate base class of any inheritance hierarchy. have seen the class named 'object' called that. Correct. The earlier comment was that class S( object ): is 'tradition', and synonymous with: class S: (not disputing the concept of "object" as the base class) Not correct. Please see last paragraph from previous message: On Sat, Feb 17, 2024 at 7:06 PM dn via Python-list mailto:python-list@python.org>> wrote: ... PS please reply to the list - there may be others who can learn from, or contribute to, this conversation! ... -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Using __new__
On 18/02/24 12:48, Jonathan Gossage wrote: The problem that I am facing is that when the superclass is not 'object', the __init__ method may well need arguments. I do not know how to determine if the superclass is 'object'. For what it is worth, any attempt to use this with different arguments should return the initial singleton and ignore further attempts to create a second instance. 1 "object" don't understand. Perhaps give us a broader description of the problem? Remember also ABCs (Abstract Base Classes). 2 arguments yes, must accommodate arguments in __new__() if some/same are needed in __init__() However, when using the default "object", the super() does not need, use, or want, any arguments to be passed. 3 singleton don't think that is happening! PS please reply to the list - there may be others who can learn from, or contribute to, this conversation! -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Using __new__
On 18/02/24 11:35, Jonathan Gossage via Python-list wrote: I am attempting to use the __new__ method in the following code: class SingletonExample(object): _instance = None def __new__(cls, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls, **kwargs) return cls._instance def __init__(self, **kwargs) -> None: our_attributes = ('h', 'x') if kwargs is not None: for k, v in kwargs.items(): if k in our_attributes: setattr(self, k, v) a = SingletonExample(h=1) and I get the following result: (PRV) jonathan@jfgdev:/PR$ python -m Library.Testing.test2 Traceback (most recent call last): File "", line 198, in _run_module_as_main File "", line 88, in _run_code File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 16, in a = SingletonExample(h=1) ^ File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 6, in __new__ cls._instance = super().__new__(cls, **kwargs) ^^ TypeError: object.__new__() takes exactly one argument (the type to instantiate) I am quite puzzled as it looks as if this code will not work if the super-class is 'object'. Any suggestions on how to proceed? Don't be puzzled. Read the error-message. Change the super-call to: cls._instance = super().__new__(cls) and happiness will follow... That said, mystifications - not sure if this meets the/your definition* of "singleton", because: - it can be aliased, eg a = SingletonExample(h=1) b = SingletonExample(x=2) - when it is, the effect is an accumulation of attributes and values a = SingletonExample(h=1) b = SingletonExample(h=2) print( a.__dict__, b.__dict__, ) - it can be re-created with a different value, eg a = SingletonExample(h=1) a = SingletonExample(h=2) - and can be 'regenerated': a = SingletonExample(h=1) a = SingletonExample(x=2) - all failures are silent * noting "Nowadays, the Singleton pattern has become so popular that people may call something a singleton even if it solves just one of the listed problems." (https://refactoring.guru/design-patterns/singleton) YMMV! -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Using __new__
On 2024-02-17 22:35, Jonathan Gossage via Python-list wrote: I am attempting to use the __new__ method in the following code: class SingletonExample(object): _instance = None def __new__(cls, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls, **kwargs) return cls._instance def __init__(self, **kwargs) -> None: our_attributes = ('h', 'x') if kwargs is not None: for k, v in kwargs.items(): if k in our_attributes: setattr(self, k, v) a = SingletonExample(h=1) and I get the following result: (PRV) jonathan@jfgdev:/PR$ python -m Library.Testing.test2 Traceback (most recent call last): File "", line 198, in _run_module_as_main File "", line 88, in _run_code File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 16, in a = SingletonExample(h=1) ^ File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 6, in __new__ cls._instance = super().__new__(cls, **kwargs) ^^ TypeError: object.__new__() takes exactly one argument (the type to instantiate) I am quite puzzled as it looks as if this code will not work if the super-class is 'object'. Any suggestions on how to proceed? Don't pass kwargs to object.__new__ because it doesn't expect it. Incidentally, kwargs will never be None, and there's no point in giving a return type for __init__ because it can only ever return None. -- https://mail.python.org/mailman/listinfo/python-list
Using __new__
I am attempting to use the __new__ method in the following code: class SingletonExample(object): _instance = None def __new__(cls, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls, **kwargs) return cls._instance def __init__(self, **kwargs) -> None: our_attributes = ('h', 'x') if kwargs is not None: for k, v in kwargs.items(): if k in our_attributes: setattr(self, k, v) a = SingletonExample(h=1) and I get the following result: (PRV) jonathan@jfgdev:/PR$ python -m Library.Testing.test2 Traceback (most recent call last): File "", line 198, in _run_module_as_main File "", line 88, in _run_code File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 16, in a = SingletonExample(h=1) ^ File "/mnt/ProgrammingRenaissance/Library/Testing/test2.py", line 6, in __new__ cls._instance = super().__new__(cls, **kwargs) ^^ TypeError: object.__new__() takes exactly one argument (the type to instantiate) I am quite puzzled as it looks as if this code will not work if the super-class is 'object'. Any suggestions on how to proceed? -- Jonathan Gossage -- https://mail.python.org/mailman/listinfo/python-list