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.
You can create a property by calling property() with an appropriate set of arguments and assigning its return value to a class attribute. All the arguments to property() are optional. However, you typically provide at least a setter function.
getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute. If the attribute does not exist, then it would be created.
Python passes arguments neither by reference nor by value, but by assignment.
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With