考虑以下python代码:
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'
最后一部分,我希望它是'value:3'而不是'3',因为现在我的属性'value'现在是一个属性。
是否可能,如果是,我将如何做到这一点。
答案 0 :(得分:3)
您的__getattr__
会返回属性值,而不是属性本身。当您访问getattr(self.foo, attr)
时,它会相当于self.foo.value
并返回该值,并且此时会调用该属性。
因此,您需要实现__setattr__
方法,以镜像__getattr__
并将值设置传递给包含的foo
对象。
在幕后,Python将属性实现为descriptors;他们的__get__()
method由较低级别__getattribute__
method调用,这会导致他们返回其计算值。永远不会返回属性对象本身。
以下是__setattr__
的例子:
def __setattr__(self, attr, value):
if hasattr(self, 'foo') and hasattr(self.foo, attr):
setattr(self.foo, attr, value)
return
super(Bar, self).__setattr__(attr, value)
注意:因为您的__init__
设置了self.foo
,您需要测试您的班级foo
是否存在hasattr(self, 'foo')
。您还需要调用原始__setattr__
实现以确保self.foo = Foo()
之类的内容仍然有用。