Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't a class's __new__ method in its __dict__?

Tags:

python

Brief context: I'm attempting to edit a class's default arguments to its __new__ method. I need access to the method, and I was attempting to get access in the same way I accessed its other methods - through its __dict__.

But here, we can see that its __new__ method isn't in its __dict__.

Is this related to __new__ being a Static Method? If so, why aren't those in a class's __dict__? Where are they stored in the object model?

class A(object):
    def __new__(cls, a):
        print(a)
        return object.__new__(cls)
    def f(a):
        print(a)
   ....:         

In [12]: A.__dict__['f']
Out[12]: <function __main__.A.f>

In [13]: A.__dict__['__new__']
Out[13]: <staticmethod at 0x103a6a128>

In [14]: A.__new__
Out[14]: <function __main__.A.__new__>

In [16]: A.__dict__['__new__'] == A.__new__
Out[16]: False

In [17]: A.__dict__['f'] == A.f
Out[17]: True
like image 785
Maximilian Avatar asked Oct 31 '22 17:10

Maximilian


1 Answers

A.__dict__['new'] is the staticmethod descriptor, where as A.__new__ is the actual underlying function.

https://docs.python.org/2/howto/descriptor.html#static-methods-and-class-methods

if you need to call the function, or get it by using a string (at runtime), use getattr(A, '__new__')

>>> A.__new__
<function A.__new__ at 0x02E69618>
>>> getattr(A, '__new__')
<function A.__new__ at 0x02E69618>

Python 3.5.1

class A(object):
def __new__(cls, a):
    print(a)
    return object.__new__(cls)
def f(a):
    print(a)

>>> A.__dict__['__new__']
<staticmethod object at 0x02E66B70>
>>> A.__new__
<function A.__new__ at 0x02E69618>
>>> object.__new__
<built-in method __new__ of type object at 0x64EC98E8>
>>> A.__new__(A, 'hello')
hello
<__main__.A object at 0x02E73BF0>
>>> A.__dict__['__new__'](A, 'hello')
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
>>> getattr(A, '__new__')
<function A.__new__ at 0x02E69618>
like image 62
wesm Avatar answered Nov 15 '22 05:11

wesm