2017-04-20 111 views
0

我认为用一个简单的例子来解释我试图实现的东西更容易。请看下面的代码:方法链接和访问变量

class Person(object): 
    def __init__(self): 
     self._age = None 
     self._gender = None 

    def age(self, value): 
     self._age = value 
     return self 

    def gender(self, value): 
     self._gender = value 
     return self 


p = Person().age(10).gender("male") 

assert p.age == 10 
assert p.gender == "male" 

显然因为属性指的是方法,而不是变量断言失败。 我试图搞乱__getattribute__方法,以便它解决“年龄”为“_age”,但我似乎无法找到一种方式,两种情况下工作,我不完全相信,它可能在所有,但Python已之前感到惊讶。

+0

如果你真的想用数据隐藏,这里是一个[示例](http://stackoverflow.com/questions/6304040 /现实世界中的示例中关于如何使用属性功能在python/42300481#42300481)应该让你开始的属性。 – Mike

回答

2

简答:不。你将遇到问题,每个使用/读取你的代码的人都会遇到问题,而且你花在实现它上的时间也不值得。


长答案:如果您绝对必须,您可以创建一个类,在调用时设置该属性的值,否则模仿该值的行为。要做到这一点,您必须覆盖全部magic methods,即使如此,print(type(p.age))之类的东西也不会产生<class 'int'>的预期输出。

这里有让你开始一个片断(只实施了__eq__法):

class CallableAttribute: 
    def __init__(self, owner, name): 
     self.owner= owner 
     self.name= name 

     setattr(owner, name, self) 
     self(None) 

    def __call__(self, value): 
     setattr(self.owner, '_'+self.name, value) 
     return self.owner 

    @property 
    def _value(self): 
     return getattr(self.owner, '_'+self.name) 

    def __eq__(self, other): 
     return self._value==other 

class Person(object): 
    def __init__(self): 
     CallableAttribute(self, 'age') 
     CallableAttribute(self, 'gender') 
+0

你可能是对的,我应该重新考虑设计选择。一个简短的后续问题:如果我添加:assert p.age * 2 == 20,我得到TypeError:不支持的操作数类型(s)*:'instance'和'int' - 有没有办法绕过这个一个优雅的方式? –

+0

@MattImmer是的,你只需重写['__mul__'](https://docs.python.org/3/reference/datamodel.html#object.__mul__)函数。 –

+0

谢谢!我会注意到这样做是可能的但不好的做法,可能会考虑替代设计。 –