Consider the following python code:
class Foo(object):
def __init__(self, value):
self._value = value
@property
def value(self):
return "value: {v}".format(v=self._value)
@value.setter
def value(self, value):
self._value = value
class Bar(object):
def __init__(self):
self.foo = Foo('foo')
def __getattr__(self, attr, *args, **kwargs):
"""
Intercepts attribute calls, and if we don't have it, look at the
webelement to see if it has the attribute.
"""
# Check first to see if it looks like a method, if not then just return
# the attribute the way it is.
# Note: this has only been tested with variables, and methods.
if not hasattr(getattr(self.foo, attr), '__call__'):
return getattr(self.foo, attr)
def callable(*args, **kwargs):
'''
Returns the method from the webelement module if found
'''
return getattr(self.foo, attr)(*args, **kwargs)
return callable
>>> b = Bar()
>>> b.foo
<__main__.Foo object at 0x819410>
>>> b.foo.value
'value: foo'
>>> b.foo.value = '2'
>>> b.foo.value
'value: 2'
>>> b.value
'value: 2'
>>> b.value = '3'
>>> b.value
'3'
That last part, I want it to be ‘value: 3’ instead of ‘3’ because now my property ‘value’ is now an attribute instead.
Is it possible, and if it is how would I would I do that.
Your
__getattr__returns the property value, not the property itself. When you accessgetattr(self.foo, attr)it does the equivalent ofself.foo.valueand returns that, and the property is called at that time.You thus need to implement a
__setattr__method too, to mirror the__getattr__and pass on the value setting to the containedfooobject.Under the hood, Python implements properties as descriptors; their
__get__()method is called by the lower-level__getattribute__method, which causes them to return their computed value. It is never the property object itself that is returned.Here’s an example
__setattr__:Note: because your
__init__setsself.foo, you need to test iffooexists on your class (hasattr(self, 'foo'). You also need to call the original__setattr__implementation to make sure that things likeself.foo = Foo()work still.