Re: Using __new__

2024-02-17 Thread dn via Python-list

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__

2024-02-17 Thread dn via Python-list

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__

2024-02-17 Thread dn via Python-list

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__

2024-02-17 Thread MRAB via Python-list

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__

2024-02-17 Thread Jonathan Gossage via Python-list
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