I'm very new to Python, and I'm using Python 3.3.1.
class Parent: # define parent class
parentAttr = 100
age = 55
def __init__(self):
print ("Calling parent constructor")
def setAttr(self, attr):
Parent.parentAttr = attr
class Child(Parent):
def childMethod(self):
print ('Calling child method')
Now I'll create
c=child
c.[here every thing will appear methods and attr (age,setAttr)]
How can I distinguish between methods and atrributes? I mean, when do I use c.SetAtrr(Argument), and c.SetAtrr=value?
Methods are attributes too. They just happen to be callable objects.
You can detect if an object is callable by using the callable() function:
>>> def foo(): pass
...
>>> callable(foo)
True
>>> callable(1)
False
When you call a method, you look up the attribute (a getattr() operation) and then call the result:
c.setAttr(newvalue)
is two steps; finding the attribute (which in this case looks up the attribute on the class, and treats it as a descriptor), then calls the resulting object, a method.
When you assign to an attribute, you rebind that name to a new value:
c.setAttr = 'something else'
would be a setattr() operation.
If you wanted to intercept getting and setting attributes on instances of your class, you could provide the attribute access hooks, __getattr__, __setattr__ and __delattr__.
If you wanted to add a method to an instance, you would have to treat the function as a descriptor object, which produces a method object:
>>> class Foo: pass
...
>>> foo = Foo() # instance
>>> def bar(self): pass
...
>>> bar
<function bar at 0x10b85a320>
>>> bar.__get__(foo, Foo)
<bound method Foo.bar of <__main__.Foo instance at 0x10b85b830>>
The return value of function.__get__(), when given an instance and a class, is a bound method. Calling that method will call the underlying function with self bound to the instance.
And speaking of descriptors, the property() function returns a descriptor too, making it possible to have functions that behave like attributes; they can intercept the getattr(), setattr() and delattr() operations for just that attribute and turn it into a function call:
>>> class Foo:
... #property
... def bar(self):
... return "Hello World!"
...
>>> foo = Foo()
>>> foo.bar
"Hello World!"
Accessing .bar invoked the bar property get hook, which then calls the original bar method.
In almost all situations, you are not going to need the callable() function; you document your API, and provide methods and attributes and the user of your API will figure it out without testing each and every attribute to see if it is callable. With properties, you have the flexibility of providing attributes that are really callables in any case.
Related
Recently, I was looking into the "getattr" method, and one interesting behaviour is that it could return a method of a class instance and assign it to a variable. Here's the example I played with:
class Example:
def some_method(self, param1):
print(param1)
example = Example()
method1 = getattr(example, "some_method")
print(method1)
method1("hi")
And here's the output:
<bound method Example.some_method of <__main__.Example object at 0x7f82cbcb2850>>
hi
I do understand for the first line of the output that the method1 is a "bound method" type related to the actual instance example. But for the function call involving the method method1("hi"), the "self" parameter is omitted, only the "param1" value is given. I wonder how this function call is processed successfully and where the "self" parameter is actually stored internally.
Methods rely on the mechanism called descriptors. Any type can be made a descriptor by implementing methods such as __get__. For example:
class D:
def __get__(self, obj, type=None):
return f'Some value from {obj.__class__.__name__}'
class A:
d = D()
print(A().d) # 'Some value from A'
Python attribute access mechanism will recognize the descriptor and delegate the access logic to its __get__(), __set__(), etc. Now, the plot twist is that Python functions also implement the descriptor protocol, that defines how they behave when accessed as methods. For example, if we have a method A.f():
class A:
def __init__(self, x):
self.x = x
def f(self, y):
return self.x + y
then this code:
a = A(2)
print(a.f(3)) # prints 5
in fact runs as:
a = A(2)
bound_f = A.__get__(a)
print(bound_f(3)) # also prints 5
So when a function is accessed as a non-static method, it intercepts the access via te descriptor protocol and returns a bound method object, with attribute __self__ set to the object on which it was accessed:
>>> print(bound_f)
<bound method A.f of <__main__.A object at 0x7fc13db99ac0>>
>>> print(bound_f.__self__)
<__main__.A at 0x7fc13db99ac0>
Static, class methods and properties are also implemented using descriptors.
Normally in Python, it is possible to detect whether a method has been overridden in a subclass using the following technique:
>>> class Foo:
... def mymethod(self): pass
...
>>> class Bar(Foo): pass
...
>>> Bar.mymethod is Foo.mymethod
True
The expression Bar.mymethod is Foo.mymethod will evaluate to True if the method from Foo has not been overridden in Bar, but will evaluate to False if the method has been overridden in Bar. This technique works well with dunder methods inherited from object, as well as non-dunder methods:
>>> Bar.__new__ is Foo.__new__
True
>>> Bar.__eq__ is Foo.__eq__
True
We can formalise this logic in a function like so:
def method_has_been_overridden(superclass, subclass, method_name):
"""
Return `True` if the method with the name `method_name`
has been overridden in the subclass
or an intermediate class in the method resolution order
"""
if not issubclass(subclass, superclass):
raise ValueError(
"This function only makes sense if `subclass` is a subclass of `superclass`"
)
subclass_method = getattr(subclass, method_name)
if not callable(method):
raise ValueError(f"'{subclass.__name__}.{method_name}' is not a method")
return subclass_method is not getattr(superclass, method_name, object())
However, this technique fails when it comes to two methods: __init_subclass__ and __subclasshook__:
>>> class Foo: pass
...
>>> class Bar(Foo): pass
...
>>> Bar.__init_subclass__ is Foo.__init_subclass__
False
>>> Bar.__subclasshook__ is Foo.__subclasshook__
False
And, for an even more perplexing example:
>>> type.__init_subclass__ is type.__init_subclass__
False
I have two questions:
Why does this technique fail with these methods, and these methods only? (I have not been able to find any other examples where this technique fails -- but if there are any, I'd love to know about them!)
Is there an alternative technique that can be used to detect if __init_subclass__ or __subclasshook__ have been defined in a subclass after being left undefined in the superclass?
__init_subclass__ is special-cased to be a class method, whether you decorate it with classmethod or not. Just like Foo().mymethod returns a new method instance every time you access the attribute via a class instance, Foo.__init_subclass__ produces a new instance method every time you access the attribute via the class itself.
__subclasshook__, on the other hand, must be declared as a class method to work properly. It is not assumed to be a class method if you define it as a simple function/instance method.
__init_subclass__ is a special method, in that it is implicitly a classmethod even if you do not decorate it with #classmethod when defining it. However, the issue here does not arise from the fact that __init_subclass__ is a special method. Instead, there is a fundamental error in the technique you are using to detect whether a method has been overridden in a subclass: it won't work with any classmethods at all:
>>> class Foo:
... def mymethod(self): pass
... #classmethod
... def my_classmethod(cls): pass
...
>>> class Bar(Foo): pass
...
>>> Bar.mymethod is Foo.mymethod
True
>>> Bar.my_classmethod is Foo.my_classmethod
False
This is because of how bound methods in Python work: methods, in Python, are descriptors.
Observe the equivalence of the following lines of code with respect to instance methods. The first (more normal) way of calling mymethod on the instance f is merely syntactic sugar for the second way of calling the method on the instance f:
>>> class Foo:
... def mymethod(self):
... print('Instance method')
...
>>> f = Foo()
>>> f.mymethod()
Instance method
>>> Foo.__dict__['mymethod'].__get__(f, Foo)()
Instance method
Calling __get__ on the unbound method in Foo.__dict__ produces a new object each time; it is only by accessing the instance method on the class that we can test for identity, as you do in your question. However, with regards to classmethods, even accessing the method from the class will call __get__ on the method:
>>> class Foo:
... #classmethod
... def my_classmethod(cls):
... print('Class method')
...
>>> Foo.my_classmethod is Foo.my_classmethod
False
>>> Foo.my_classmethod()
Class method
>>> Foo.__dict__['my_classmethod'].__get__(Foo, Foo)()
Class method
What about __new__?
Your question points out that your existing method works with __new__. That's strange -- we've just established that this method doesn't work with classmethods, and __new__ certainly looks like a classmethod. The first parameter of __new__ is named cls, after all! However, the Python documentation makes clear that this isn't the case at all:
object.__new__(cls[, ...])
Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument.
It's a staticmethod, not a classmethod! Mystery solved.
A better way of detecting whether a subclass overrides a method from a superclass
The only sure-fire way of knowing for sure if a method has been overridden in a subclass is by traversing the __dict__ of each class in the method resolution order:
def method_has_been_overridden(superclass, subclass, method_name):
"""
Return `True` if the method with the name `method_name`
has been overridden in the subclass
or an intermediate class in the method resolution order
"""
if not issubclass(subclass, superclass):
raise ValueError(
"This function only makes sense if `subclass` is a subclass of `superclass`"
)
subclass_method = getattr(subclass, method_name)
if not callable(subclass_method):
raise ValueError(f"'{subclass.__name__}.{method_name}' is not a method")
for cls in subclass.__mro__:
if cls is superclass:
return False
if method_name in cls.__dict__:
return True
This function can correctly determine whether or not __init_subclass__, or any other classmethod, has been overridden in a subclass:
>>> class Foo: pass
...
>>> class Bar(Foo): pass
...
>>> class Baz(Foo):
... def __init_subclass__(cls, *args, **kwargs):
... return super().__init_subclass__(*args, **kwargs)
>>> method_has_been_overridden(Foo, Bar, '__init_subclass__')
False
>>> method_has_been_overridden(Foo, Baz, '__init_subclass__')
True
Many thanks to #chepner and U12-Forward, whose excellent answers helped me figure this problem out.
__init_subclass__ and __subclasshook__ are class methods. As you can see here:
>>> Bar.__sizeof__
<method '__sizeof__' of 'object' objects>
>>> Bar.__eq__
<slot wrapper '__eq__' of 'object' objects>
>>> Bar.__subclasshook__
<built-in method __subclasshook__ of type object at 0x000002D70AAC5340>
>>> Bar.__init_subclass__
<built-in method __init_subclass__ of type object at 0x000002D70AAC5340>
>>> Foo.__init_subclass__
<built-in method __init_subclass__ of type object at 0x000002D70AACAF70>
>>>
__init_subclass__ and __subclasshook__ refer to their classes that are different instances, Bar's hex is 0x000002D70AAC5340, and Foo's hex is 0x000002D70AACAF70.
As you can see in the documentation of __init_subclass__, it says:
classmethod object.__init_subclass__(cls)
It says "classmethod".
I hope someone can answer this that has a good deep understanding of Python :)
Consider the following code:
>>> class A(object):
... pass
...
>>> def __repr__(self):
... return "A"
...
>>> from types import MethodType
>>> a = A()
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>> setattr(a, "__repr__", MethodType(__repr__, a, a.__class__))
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>>
Notice how repr(a) does not yield the expected result of "A" ?
I want to know why this is the case and if there is a way to achieve this...
I contrast, the following example works however (Maybe because we're not trying to override a special method?):
>>> class A(object):
... def foo(self):
... return "foo"
...
>>> def bar(self):
... return "bar"
...
>>> from types import MethodType
>>> a = A()
>>> a.foo()
'foo'
>>> setattr(a, "foo", MethodType(bar, a, a.__class__))
>>> a.foo()
'bar'
>>>
Python usually doesn't call the special methods (those with name surrounded by __) on the instance, but only on the class. (Although this is an implementation detail, it's characteristic of CPython, the standard interpreter.) So there's no way to override __repr__() directly on an instance and make it work. Instead, you need to do something like so:
class A(object):
def __repr__(self):
return self._repr()
def _repr(self):
return object.__repr__(self)
Now you can override __repr__() on an instance by substituting _repr().
As explained in Special Method Lookup:
For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary … In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass
(The part I've snipped out explains the rationale behind this, if you're interested in that.)
Python doesn't document exactly when an implementation should or shouldn't look up the method on the type; all it documents is, in effect, that implementations may or may not look at the instance for special method lookups, so you shouldn't count on either.
As you can guess from your test results, in the CPython implementation, __repr__ is one of the functions looked up on the type.
Things are slightly different in 2.x, mostly because of the presence of classic classes, but as long as you're only creating new-style classes you can think of them as the same.
The most common reason people want to do this is to monkey-patch different instances of an object to do different things. You can't do that with special methods, so… what can you do? There's a clean solution, and a hacky solution.
The clean solution is to implement a special method on the class that just calls a regular method on the instance. Then you can monkey patch that regular method on each instance. For example:
class C(object):
def __repr__(self):
return getattr(self, '_repr')()
def _repr(self):
return 'Boring: {}'.format(object.__repr__(self))
c = C()
def c_repr(self):
return "It's-a me, c_repr: {}".format(object.__repr__(self))
c._repr = c_repr.__get__(c)
The hacky solution is to build a new subclass on the fly and re-class the object. I suspect anyone who really has a situation where this is a good idea will know how to implement it from that sentence, and anyone who doesn't know how to do so shouldn't be trying, so I'll leave it at that.
The reason for this is special methods (__x__()) are defined for the class, not the instance.
This makes sense when you think about __new__() - it would be impossible to call this on an instance as the instance doesn't exist when it's called.
So you can do this on the class as a whole if you want to:
>>> A.__repr__ = __repr__
>>> a
A
Or on an individual instance, as in kindall's answer. (Note there is a lot of similarity here, but I thought my examples added enough to post this as well).
For new style classes, Python uses a special method lookup that bypasses instances. Here an excerpt from the source:
1164 /* Internal routines to do a method lookup in the type
1165 without looking in the instance dictionary
1166 (so we can't use PyObject_GetAttr) but still binding
1167 it to the instance. The arguments are the object,
1168 the method name as a C string, and the address of a
1169 static variable used to cache the interned Python string.
1170
1171 Two variants:
1172
1173 - lookup_maybe() returns NULL without raising an exception
1174 when the _PyType_Lookup() call fails;
1175
1176 - lookup_method() always raises an exception upon errors.
1177
1178 - _PyObject_LookupSpecial() exported for the benefit of other places.
1179 */
You can either change to an old-style class (don't inherit from object) or you can add dispatcher methods to the class (methods that forward lookups back to the instance). For an example of instance dispatcher methods, see the recipe at http://code.activestate.com/recipes/578091
TLDR: It is impossible to define proper, unbound methods on instances; this applies to special methods as well. Since bound methods are first-class objects, in certain circumstances the difference is not noticeable.
However, special methods are always looked up as proper, unbound methods by Python when needed.
You can always manually fall back to a special method that uses the more generic attribute access. Attribute access covers both bound methods stored as attributes as well as unbound methods that are bound as needed. This is similar to how __repr__ or other methods would use attributes to define their output.
class A:
def __init__(self, name):
self.name = name
def __repr__(self):
# call attribute to derive __repr__
return self.__representation__()
def __representation__(self):
return f'{self.__class__.__name__}({self.name})'
def __str__(self):
# return attribute to derive __str__
return self.name
Unbound versus Bound Methods
There are two meanings to a method in Python: unbound methods of a class and bound methods of an instance of that class.
An unbound method is a regular function on a class or one of its base classes. It can be defined either during class definition, or added later on.
>>> class Foo:
... def bar(self): print('bar on', self)
...
>>> Foo.bar
<function __main__.Foo.bar(self)>
An unbound method exists only once on the class - it is the same for all instances.
A bound method is an unbound method which has been bound to a specific instance. This usually means the method was looked up through the instance, which invokes the function's __get__ method.
>>> foo = Foo()
>>> # lookup through instance
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> # explicit descriptor invokation
>>> type(foo).bar.__get__(foo, type(Foo))
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
As far as Python is concerned, "a method" generally means an unbound method that is bound to its instance as required. When Python needs a special method, it directly invokes the descriptor protocol for the unbound method. In consequence, the method is looked up on the class; an attribute on the instance is ignored.
Bound Methods on Objects
A bound method is created anew every time it is fetched from its instance. The result is a first-class object that has identity, can be stored and passed around, and be called later on.
>>> foo.bar is foo.bar # binding happens on every lookup
False
>>> foo_bar = foo.bar # bound methods can be stored
>>> foo_bar() # stored bound methods can be called later
bar on <__main__.Foo object at 0x10c3b6390>
>>> foo_bar()
bar on <__main__.Foo object at 0x10c3b6390>
Being able to store bound methods means they can also be stored as attributes. Storing a bound method on its bound instance makes it appear similar to an unbound method. But in fact a stored bound method behaves subtly different and can be stored on any object that allows attributes.
>>> foo.qux = foo.bar
>>> foo.qux
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> foo.qux is foo.qux # binding is not repeated on every lookup!
True
>>> too = Foo()
>>> too.qux = foo.qux # bound methods can be stored on other instances!
>>> too.qux # ...but are still bound to the original instance!
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> import builtins
>>> builtins.qux = foo.qux # bound methods can be stored...
>>> qux # ... *anywhere* that supports attributes
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
As far as Python is concerned, bound methods are just regular, callable objects. Just as it has no way of knowing whether too.qux is a method of too, it cannot deduce whether too.__repr__ is a method either.
I hope someone can answer this that has a good deep understanding of Python :)
Consider the following code:
>>> class A(object):
... pass
...
>>> def __repr__(self):
... return "A"
...
>>> from types import MethodType
>>> a = A()
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>> setattr(a, "__repr__", MethodType(__repr__, a, a.__class__))
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>>
Notice how repr(a) does not yield the expected result of "A" ?
I want to know why this is the case and if there is a way to achieve this...
I contrast, the following example works however (Maybe because we're not trying to override a special method?):
>>> class A(object):
... def foo(self):
... return "foo"
...
>>> def bar(self):
... return "bar"
...
>>> from types import MethodType
>>> a = A()
>>> a.foo()
'foo'
>>> setattr(a, "foo", MethodType(bar, a, a.__class__))
>>> a.foo()
'bar'
>>>
Python usually doesn't call the special methods (those with name surrounded by __) on the instance, but only on the class. (Although this is an implementation detail, it's characteristic of CPython, the standard interpreter.) So there's no way to override __repr__() directly on an instance and make it work. Instead, you need to do something like so:
class A(object):
def __repr__(self):
return self._repr()
def _repr(self):
return object.__repr__(self)
Now you can override __repr__() on an instance by substituting _repr().
As explained in Special Method Lookup:
For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary … In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass
(The part I've snipped out explains the rationale behind this, if you're interested in that.)
Python doesn't document exactly when an implementation should or shouldn't look up the method on the type; all it documents is, in effect, that implementations may or may not look at the instance for special method lookups, so you shouldn't count on either.
As you can guess from your test results, in the CPython implementation, __repr__ is one of the functions looked up on the type.
Things are slightly different in 2.x, mostly because of the presence of classic classes, but as long as you're only creating new-style classes you can think of them as the same.
The most common reason people want to do this is to monkey-patch different instances of an object to do different things. You can't do that with special methods, so… what can you do? There's a clean solution, and a hacky solution.
The clean solution is to implement a special method on the class that just calls a regular method on the instance. Then you can monkey patch that regular method on each instance. For example:
class C(object):
def __repr__(self):
return getattr(self, '_repr')()
def _repr(self):
return 'Boring: {}'.format(object.__repr__(self))
c = C()
def c_repr(self):
return "It's-a me, c_repr: {}".format(object.__repr__(self))
c._repr = c_repr.__get__(c)
The hacky solution is to build a new subclass on the fly and re-class the object. I suspect anyone who really has a situation where this is a good idea will know how to implement it from that sentence, and anyone who doesn't know how to do so shouldn't be trying, so I'll leave it at that.
The reason for this is special methods (__x__()) are defined for the class, not the instance.
This makes sense when you think about __new__() - it would be impossible to call this on an instance as the instance doesn't exist when it's called.
So you can do this on the class as a whole if you want to:
>>> A.__repr__ = __repr__
>>> a
A
Or on an individual instance, as in kindall's answer. (Note there is a lot of similarity here, but I thought my examples added enough to post this as well).
For new style classes, Python uses a special method lookup that bypasses instances. Here an excerpt from the source:
1164 /* Internal routines to do a method lookup in the type
1165 without looking in the instance dictionary
1166 (so we can't use PyObject_GetAttr) but still binding
1167 it to the instance. The arguments are the object,
1168 the method name as a C string, and the address of a
1169 static variable used to cache the interned Python string.
1170
1171 Two variants:
1172
1173 - lookup_maybe() returns NULL without raising an exception
1174 when the _PyType_Lookup() call fails;
1175
1176 - lookup_method() always raises an exception upon errors.
1177
1178 - _PyObject_LookupSpecial() exported for the benefit of other places.
1179 */
You can either change to an old-style class (don't inherit from object) or you can add dispatcher methods to the class (methods that forward lookups back to the instance). For an example of instance dispatcher methods, see the recipe at http://code.activestate.com/recipes/578091
TLDR: It is impossible to define proper, unbound methods on instances; this applies to special methods as well. Since bound methods are first-class objects, in certain circumstances the difference is not noticeable.
However, special methods are always looked up as proper, unbound methods by Python when needed.
You can always manually fall back to a special method that uses the more generic attribute access. Attribute access covers both bound methods stored as attributes as well as unbound methods that are bound as needed. This is similar to how __repr__ or other methods would use attributes to define their output.
class A:
def __init__(self, name):
self.name = name
def __repr__(self):
# call attribute to derive __repr__
return self.__representation__()
def __representation__(self):
return f'{self.__class__.__name__}({self.name})'
def __str__(self):
# return attribute to derive __str__
return self.name
Unbound versus Bound Methods
There are two meanings to a method in Python: unbound methods of a class and bound methods of an instance of that class.
An unbound method is a regular function on a class or one of its base classes. It can be defined either during class definition, or added later on.
>>> class Foo:
... def bar(self): print('bar on', self)
...
>>> Foo.bar
<function __main__.Foo.bar(self)>
An unbound method exists only once on the class - it is the same for all instances.
A bound method is an unbound method which has been bound to a specific instance. This usually means the method was looked up through the instance, which invokes the function's __get__ method.
>>> foo = Foo()
>>> # lookup through instance
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> # explicit descriptor invokation
>>> type(foo).bar.__get__(foo, type(Foo))
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
As far as Python is concerned, "a method" generally means an unbound method that is bound to its instance as required. When Python needs a special method, it directly invokes the descriptor protocol for the unbound method. In consequence, the method is looked up on the class; an attribute on the instance is ignored.
Bound Methods on Objects
A bound method is created anew every time it is fetched from its instance. The result is a first-class object that has identity, can be stored and passed around, and be called later on.
>>> foo.bar is foo.bar # binding happens on every lookup
False
>>> foo_bar = foo.bar # bound methods can be stored
>>> foo_bar() # stored bound methods can be called later
bar on <__main__.Foo object at 0x10c3b6390>
>>> foo_bar()
bar on <__main__.Foo object at 0x10c3b6390>
Being able to store bound methods means they can also be stored as attributes. Storing a bound method on its bound instance makes it appear similar to an unbound method. But in fact a stored bound method behaves subtly different and can be stored on any object that allows attributes.
>>> foo.qux = foo.bar
>>> foo.qux
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> foo.qux is foo.qux # binding is not repeated on every lookup!
True
>>> too = Foo()
>>> too.qux = foo.qux # bound methods can be stored on other instances!
>>> too.qux # ...but are still bound to the original instance!
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
>>> import builtins
>>> builtins.qux = foo.qux # bound methods can be stored...
>>> qux # ... *anywhere* that supports attributes
<bound method Foo.bar of <__main__.Foo object at 0x10c3b6390>>
As far as Python is concerned, bound methods are just regular, callable objects. Just as it has no way of knowing whether too.qux is a method of too, it cannot deduce whether too.__repr__ is a method either.
If I have this:
class foo(object):
#property
def bar(self):
return 0
f = foo()
How do I get a reference to f.bar without actually invoking the method, if this is even possible?
Edited to add: What I want to do is write a function that iterates over the members of f and does something with them (what is not important). Properties are tripping me up because merely naming them in getattr() invokes their __get__() method.
get_dict_attr (below) looks up attr in a given object's __dict__, and returns the associated value if its there. If attr is not a key in that __dict__, the object's MRO's __dict__s are searched. If the key is not found, an AttributeError is raised.
def get_dict_attr(obj, attr):
for obj in [obj] + obj.__class__.mro():
if attr in obj.__dict__:
return obj.__dict__[attr]
raise AttributeError
For example,
class Foo(object):
x=1
def bar(self):
pass
#property
def baz(self):
return 0
foo=Foo()
print(get_dict_attr(foo,'x'))
# 1
print(get_dict_attr(foo,'bar'))
# <unbound method Foo.bar>
print(get_dict_attr(foo,'baz'))
# <property object at 0xb77c0dc4>
print(get_dict_attr(foo,'y'))
# AttributeError
Note that this is very different than the normal rules of attribute lookup.
For one thing, data-descriptors in obj.__class__.__dict__ (descriptors with both __get__ and __set__ methods) normally have precedence over values in obj.__dict__. In get_dict_attr, obj.__dict__ has precedence.
get_dict_attr does not try calling __getattr__.
Finally, get_dict_attr will only work with objects obj which are instances of new-style classes.
Nevertheless, I hope it is of some help.
class Foo(object):
#property
def bar(self):
return 0
f = Foo()
This references the property bar:
print(Foo.bar)
# <property object at 0xb76d1d9c>
You see bar is a key in Foo.__dict__:
print(Foo.__dict__['bar'])
# <property object at 0xb775dbbc>
All properties are descriptors, which implies it has a __get__ method:
print(Foo.bar.__get__)
# <method-wrapper '__get__' of property object at 0xb76d7d74>
You can call the method by passing the object f, and the class of f as arguments:
print(Foo.bar.__get__(f,Foo))
# 0
I am fond of the following diagram. Vertical lines show the relationship between an object and the object's class.
When you have this situation:
Foo B
| Foo.__dict__={'bar':b} | B.__dict__={'__get__':...}
| \ |
f `--------> b
f.bar causes b.__get__(f,Foo) to be called.
This is explained in detail here.
Short answer:
Properties return its self when they called from class: MyClass.my_prop
Also, they have fields that contain a link to the actual methods: fget, fset and fdel.
Description:
So, my_class.my_prop (where my_class = MyClass()) returns the value, but MyClass.my_prop returns the property object and MyClass.my_prop.fget returns the getter method of this property. The self is not linked to it, so it should be populated during the call: MyClass.my_prop.fget(my_class)
Example:
class MyClass:
my_prop = property(lambda self: 'get', lambda self, x: print('set', x))
setter = MyClass.my_prop.fset
getter = MyClass.my_prop.fget
my_class = MyClass()
setter(my_class, 5) # equals my_class.my_prop = 5
print(getter(my_class)) # equals print(my_class.my_prop)
I ran into a similar situation to this and none of the other answers helped me, so here's an alternate approach.
My situation was slightly different, as instead of just having a #property, I was mixing in a custom decorator that adds attributes to the wrapped method. So eg normally I'd have something like this:
class Foo:
#my_decorator
def bar(self):
return do_stuff() # Pretend this is non-trivial
My #my_decorator would then give me access to self.bar.my_attribute that had some data I need to access sometimes. This works great for functions and methods, but I hit a snag when trying to mix it with #property because the property hides the reference to the method (self.bar.my_attribute fails because self.bar returns the return value of the method, which doesn't have the my_attribute that I want).
I'd use #property as the outer decorator like so:
class Foo:
#property
#my_decorator
def bar(self):
return do_stuff() # Pretend this is non-trivial
And then the solution is to access my_attribute as Foo.bar.fget.my_attribute (the important detail here is that accessing the property from the class returns the property object, whereas accessing the property from an instance just calls the method and returns the value, without access to the reference to the original method).
TL;DR: If you need a reference to the method that provides your #property, you need to use YourClassName.your_property.fget.
In your case,
class Foo(object):
#property
def bar(self):
return 0
f = Foo()
You can access the property through the class Foo. These are all equivalent:
Foo.bar
Foo.__dict__['bar']
f.__class__.__dict__['bar']
=> <property at 0x4920c28>
As you can see, this is a property instance. On a property you have a method called fget which returns the 'getter' value.
isinstance(Foo.bar, property)
=> True
Foo.bar.fget
=> <function Foo.bar at 0x0000014DC0CF21F0>
You can call this function (an instance method) directly.
Foo.bar.fget(f)
=> 0
Note: you have to supply the object f (the self argument) to fget yourself, because when accessed through the class, the class does not know the instance f yet. In other words, instance method Foo.bar.fget is not yet 'bound' to f.
One thing you should know is that data descriptors (i.e., properties) only work when they are applied to (new-style) classes (see http://docs.python.org/reference/datamodel.html#implementing-descriptors). Copying them to an object will not create the property on that object. You need to copy them to a (new-style) class to take effect.
Why not just lambdify it?
bar_getter = lambda: f.bar
Done.
I'm going to say ignore the other answers because they are bad.
You can get a reference to the property simply by foo.bar
As for what you're trying to do iterating over the members of f, see below for specifics.
The long answer: what you have to understand are that methods in Python do not belong to instances, but are attributes of the class object. For example,
class Foo:
def bar(self):
pass
foo = Foo()
if you call foo.bar(), Python first checks to see if foo has bar (it doesn't), then it checks if Foo has bar, which it does. Python then "binds" foo.bar to Foo.bar(foo), and calls that.
The same is true for properties. I don't know the exact process (and I imagine it differs between implementations), but essentially Python looks for foo.bar, then Foo.bar, sees that it is a property, so evaluates its getter and returns that.