This question already has answers here:
Schrödinger's variable: the __class__ cell magically appears if you're checking for its presence?
(2 answers)
Closed 2 years ago.
I found this quirk while checking out how to use super.
In [1]: super?
Init signature: super(self, /, *args, **kwargs)
Docstring:
super() -> same as super(__class__, <first argument>)
...
Note that the first example uses __class__ directly.
And somehow, __class__ can be used inside instance methods:
class Test():
def __init__(self):
print(__class__)
def foo(self):
print(__class__)
def bar(self):
print(bar)
t = Test() # <class '__main__.Test'>
t.foo() # <class '__main__.Test'>
t.bar() # NameError: name 'bar' is not defined
Can anyone explain why this is the case?
So, it is a quirk for the compiler to find the parent class.
From Python Data Model:
__class__ is an implicit closure reference created by the compiler if any methods in a class body refer to either __class__ or super. This
allows the zero argument form of super() to correctly identify the
class being defined based on lexical scoping, while the class or
instance that was used to make the current call is identified based on
the first argument passed to the method.
Related
This question already has answers here:
Why does a python descriptor __get__ method accept the owner class as an arg?
(4 answers)
Closed 1 year ago.
As described here:
https://docs.python.org/3/reference/datamodel.html#object.__get__
The two arguments ('self' excluded) passed to the __get__ method are the object and a class through which the attribute was accessed, respectively. Isn't the second argument redundant?
Furthermore, why is there a need to make a distinction between object and class access when 'classes' are also objects?
So, to me it looks like there are two possibilities:
Attribute gets accessed from an object, in which case the owner argument will be equal to type(instance), so it brings no new information
Attribute gets accessed from a class (an object of 'type'), in which case the source object just sits in the owner argument with the instance being None
It looks to me like the same functionality could be achieved if only one argument was used (for example instance) which will always hold the originating object, regardless of whether it is a "class" or not. If that information is really needed, one could just check using isinstance(instance, type).
So, why the need for both arguments?
The reason they are separate comes from the original prose in PEP 252
__get__(): a function callable with one or two arguments that retrieves the attribute value from an object. This is also referred to as a "binding" operation, because it may return a "bound method" object in the case of method descriptors. The first argument, X, is the object from which the attribute must be retrieved or to which it must be bound. When X is None, the optional second argument, T, should be meta-object and the binding operation may return an unbound method restricted to instances of T. When both X and T are specified, X should be an instance of T. Exactly what is returned by the binding operation depends on the semantics of the descriptor; for example, static methods and class methods (see below) ignore the instance and bind to the type instead.
in other words, the two arguments allow for differentiation between an "unbound" descriptor (one called upon the class) and a "bound" descriptor (one called upon the instance). one example of where you see this often but don't really think about it is classmethod (which uses the owner parameter and ignores the instance parameter).
If you're always using "bound" descriptors, you're right the owner is a bit redundant since instance should be an instance of that type.
Perhaps easier to see is a classmethod descriptor implemented in pure python:
class MyClassmethod(object):
def __init__(self, func):
self._func = func
def __get__(self, instance, owner = None):
# instance is ignored, `owner` is bound to the first arg
return self._func.__get__(owner)
class C:
#MyClassmethod
def func(cls, x):
print(cls)
print(x)
C.func(1)
C().func(2)
OUTPUT = '''\
$ python3 t.py
<class '__main__.C'>
1
<class '__main__.C'>
2
'''
or consider this (somewhat incomplete) cached_class_property:
class cached_class_property:
def __init__(self, fget):
self.fget = fget
def __get__(self, obj, owner):
val = self.fget(owner)
setattr(owner, self.fget.__name__, val)
return val
class C:
#cached_class_property
def f(self):
print('calculating...')
return 42
print(C.f)
print(C().f)
OUTPUT = '''\
$ python3 t.py
calculating...
42
42
'''
note that since python3, "unbound" and "bound" methods aren't really a concept any more, but the api persists at the descriptor level -- notably functions on classes no longer validate that the type of the instance matches the owner:
class C:
def d(self):
print(self)
class D:
pass
C().d()
C.d(D())
OUTPUT = '''\
$ python3 t.py
<__main__.C object at 0x7f09576d3040>
<__main__.D object at 0x7f09576d3040>
$ python2 t.py
<__main__.C instance at 0x7efe2c8a7910>
Traceback (most recent call last):
File "t2.py", line 9, in <module>
C.d(D())
TypeError: unbound method d() must be called with C instance as first argument (got D instance instead)
'''
I have following class with a function:
class A:
def myfn():
print("In myfn method.")
Here, the function does not have self as argument. It also does not have #classmethod or #staticmethod as decorator. However, it works if called with class:
A.myfn()
Output:
In myfn method.
But give an error if called from any instance:
a = A()
a.myfn()
Error output:
Traceback (most recent call last):
File "testing.py", line 16, in <module>
a.myfn()
TypeError: myfn() takes 0 positional arguments but 1 was given
probably because self was also sent as an argument.
What kind of function will this be called? Will it be a static function? Is it advisable to use function like this in classes? What is the drawback?
Edit: This function works only when called with class and not with object/instance. My main question is what is such a function called?
Edit2: It seems from the answers that this type of function, despite being the simplest form, is not accepted as legal. However, as no serious drawback is mentioned in any of many answers, I find this can be a useful construct, especially to group my own static functions in a class that I can call as needed. I would not need to create any instance of this class. In the least, it saves me from typing #staticmethod every time and makes code look less complex. It also gets derived neatly for someone to extend my class. Although all such functions can be kept at top/global level, keeping them in class is more modular. However, I feel there should be a specific name for such a simple construct which works in this specific way and it should be recognized as legal. It may also help beginners understand why self argument is needed for usual functions in a Python class. This will only add to the simplicity of this great language.
The function type implements the descriptor protocol, which means when you access myfn via the class or an instance of the class, you don't get the actual function back; you get instead the result of that function's __get__ method. That is,
A.myfn == A.myfn.__get__(None, A)
Here, myfn is an instance method, though one that hasn't been defined properly to be used as such. When accessed via the class, though, the return value of __get__ is simply the function object itself, and the function can be called the same as a static method.
Access via an instance results in a different call to __get__. If a is an instance of A, then
a.myfn() == A.myfn.__get__(a, A)
Here , __get__ tries to return, essentially, a partial application of myfn to a, but because myfn doesn't take any arguments, that fails.
You might ask, what is a static method? staticmethod is a type that wraps a function and defines its own __get__ method. That method returns the underlying function whether or not the attribute is accessed via the class or an instance. Otherwise, there is very little difference between a static method and an ordinary function.
This is not a true method. Correctly declarated instance methods should have a self argument (the name is only a convention and can be changed if you want hard to read code), and classmethods and staticmethods should be introduced by their respective decorator.
But at a lower level, def in a class declaration just creates a function and assigns it to a class member. That is exactly what happens here: A.my_fn is a function and can successfully be called as A.my_fn().
But as it was not declared with #staticmethod, it is not a true static method and it cannot be applied on a A instance. Python sees a member of that name that happens to be a function which is neither a static nor a class method, so it prepends the current instance to the list of arguments and tries to execute it.
To answer your exact question, this is not a method but just a function that happens to be assigned to a class member.
Such a function isn't the same as what #staticmethod provides, but is indeed a static method of sorts.
With #staticmethod you can also call the static method on an instance of the class. If A is a class and A.a is a static method, you'll be able to do both A.a() and A().a(). Without this decorator, only the first example will work, because for the second one, as you correctly noticed, "self [will] also [be] sent as an argument":
class A:
#staticmethod
def a():
return 1
Running this:
>>> A.a() # `A` is the class itself
1
>>> A().a() # `A()` is an instance of the class `A`
1
On the other hand:
class B:
def b():
return 2
Now, the second version doesn't work:
>>> B.b()
2
>>> B().b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: b() takes 0 positional arguments but 1 was given
further to #chepnet's answer, if you define a class whose objects implement the descriptor protocol like:
class Descr:
def __get__(self, obj, type=None):
print('get', obj, type)
def __set__(self, obj, value):
print('set', obj, value)
def __delete__(self, obj):
print('delete', obj)
you can embed an instance of this in a class and invoke various operations on it:
class Foo:
foo = Descr()
Foo.foo
obj = Foo()
obj.foo
which outputs:
get None <class '__main__.Foo'>
get <__main__.Foo object at 0x106d4f9b0> <class '__main__.Foo'>
as functions also implement the descriptor protocol, we can replay this by doing:
def bar():
pass
print(bar)
print(bar.__get__(None, Foo))
print(bar.__get__(obj, Foo))
which outputs:
<function bar at 0x1062da730>
<function bar at 0x1062da730>
<bound method bar of <__main__.Foo object at 0x106d4f9b0>>
hopefully that complements chepnet's answer which I found a little terse/opaque
This question already has answers here:
Get defining class of unbound method object in Python 3
(5 answers)
Closed 7 years ago.
I need to:
Receive a method as argument (directly from the class, without instance)
Create an instance
Execute said method from instance
The thing is, how can I reliably get the class out of the method? I've tried researching something in the inspect module, but because there is no instance, it thinks of the method as a function rather than a method.
Here's some example of what I'm trying to do:
def execute_method(method):
cls = get_class_from_method(method)
obj = cls()
getattr(obj, method.__name__)()
def get_class_from_method(method):
pass # how?
execute_method(HelloView.say_hello)
A Python 2 method objects have a im_class attribute referencing the class of the instance they are bound to:
cls = method.im_class
For an unbound method, in Python 3, you'll be out of luck (the function is returned entirely unchanged, with no reference to the class). Python 2 returns an unbound method type with the im_class attribute still there:
>>> class Foo(object):
... def bar(self): pass
...
>>> Foo.bar.im_class
<class '__main__.Foo'>
In Python 3, your options are far more limited and are error-prone. You could look at the __qualname__ attribute of the function, and deduce from that what the class might be bound to in the global namespace:
>>> class Foo:
... def bar(self): pass
...
>>> Foo.bar
<function Foo.bar at 0x10e97b268>
>>> Foo.bar.__qualname__
'Foo.bar'
>>> Foo.bar.__qualname__.rpartition('.')[0]
'Foo'
>>> Foo.bar.__globals__.get(Foo.bar.__qualname__.rpartition('.')[0])
<class '__main__.Foo'>
However, if the class was created in a function (and is thus a local), or the class was replaced via a class decorator or simply renamed in the global namespace, the above trick at best won't work, at worst give you an entirely different object, and you can't know if this is the case.
This question already has answers here:
How can I call a function within a class?
(2 answers)
Closed 6 months ago.
How can i call a private function from some other function within the same class?
class Foo:
def __bar(arg):
#do something
def baz(self, arg):
#want to call __bar
Right now, when i do this:
__bar(val)
from baz(), i get this:
NameError: global name '_Foo__createCodeBehind' is not defined
Can someone tell me what the reason of the error is?
Also, how can i call a private function from another private function?
There is no implicit this-> in Python like you have in C/C++ etc. You have to call it on self.
class Foo:
def __bar(self, arg):
#do something
def baz(self, arg):
self.__bar(arg)
These methods are not really private though. When you start a method name with two underscores Python does some name mangling to make it "private" and that's all it does, it does not enforce anything like other languages do. If you define __bar on Foo, it is still accesible from outside of the object through Foo._Foo__bar. E.g., one can do this:
f = Foo()
f._Foo__bar('a')
This explains the "odd" identifier in the error message you got as well.
You can find it here in the docs.
__bar is "private" (in the sense that its name has been mangled), but it's still a method of Foo, so you have to reference it via self and pass self to it. Just calling it with a bare __bar() won't work; you have to call it like so: self.__bar(). So...
>>> class Foo(object):
... def __bar(self, arg):
... print '__bar called with arg ' + arg
... def baz(self, arg):
... self.__bar(arg)
...
>>> f = Foo()
>>> f.baz('a')
__bar called with arg a
You can access self.__bar anywhere within your Foo definition, but once you're outside the definition, you have to use foo_object._Foo__bar(). This helps avoid namespace collisions in the context of class inheritance.
If that's not why you're using this feature, you might reconsider using it. The convention for creating "private" variables and methods in Python is to prepend an underscore to the name. This has no syntactic significance, but it conveys to users of your code that the variable or method is part of implementation details that may change.
If a variable refers to either a function or a class method, how can I find out which one it is and get the class type in case it is a class method especially when the class is still being declared as in the given example.
eg.
def get_info(function_or_method):
print function_or_method
class Foo(object):
def __init__(self):
pass
get_info(__init__)
def bar():
pass
get_info(bar)
Update to question after the first two responses from David and J. F. Sebastian
To reemphasize a point which J.F. Sebastian alluded to, I want to be able to distinguish it when the function is being declared within the class (when the type I am getting is a function and not a bound or unbound method). ie. where the first call to get_info(__init__) happens I would like to be able to detect that its a method being declared as a part of a class.
This question came up since I am putting a decorator around it and it gets a handle to the init function and I can't actually figure out if a method is being declared within a class or as a stand alone function
You can distinguish between the two by checking the type:
>>> type(bar)
<type 'function'>
>>> type(Foo.__init__)
<type 'instancemethod'>
or
>>> import types
>>> isinstance(bar, types.FunctionType)
True
>>> isinstance(bar, types.UnboundMethodType)
True
which is the way you'd do it in an if statement.
Also, you can get the class from the im_class attribute of the method:
>>> Foo.__init__.im_class
__main__.Foo
At the time you are calling get_info(__init__) (inside class definition) the __init__ is an ordinary function.
def get_info(function_or_method):
print function_or_method
class Foo(object):
def __init__(self):
pass
get_info(__init__) # function
def bar():
pass
get_info(Foo.__init__) # unbound method
get_info(Foo().__init__) # bound method
get_info(bar) # function
Output (CPython, IronPython):
<function __init__ at ...>
<unbound method Foo.__init__>
<bound method Foo.__init__ of <__main__.Foo object at ...>>
<function bar at ...>
Output (Jython):
<function __init__ 1>
<unbound method Foo.__init__>
<method Foo.__init__ of Foo instance 2>
<function bar 3>
To reemphasize a point which J.F. Sebastian alluded to, I want to be able to distinguish it when the function is being declared within the class (when the type I am getting is a function and not a bound or unbound method). ie. where the first call to get_info(__init__) happens I would like to be able to detect that its a method being declared as a part of a class.
This question came up since I am putting a decorator around it and it gets a handle to the init function and I can't actually figure out if a method is being declared within a class or as a stand alone function
You can't. J.F. Sebastian's answer is still 100% applicable. When the body of the class definition is being executed, the class itself doesn't exist yet. The statements (the __init__ function definition, and the get_info(__init__) call) happen in a new local namespace; at the time the call to get_info occurs, __init__ is a reference to the function in that namespace, which is indistinguishable from a function defined outside of a class.