方法链接和访问变量
Method chaining and accessing variables
我认为用一个简单的例子更容易解释我想要实现的目标。考虑以下代码:
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" 解析为“_age”,但我似乎无法找到两种情况都有效的方法,而且我不完全确定它是否可能完全没有 Python 之前让我感到惊讶。
简答:不要。你会 运行 遇到问题,uses/reads 你的代码的每个人都会 运行 遇到问题,不值得你花时间来实现它。
长答案:如果绝对必要,您可以创建一个 class 来在调用时设置属性的值,否则模仿值的行为。为此,您必须覆盖 all 和 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')
我认为用一个简单的例子更容易解释我想要实现的目标。考虑以下代码:
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" 解析为“_age”,但我似乎无法找到两种情况都有效的方法,而且我不完全确定它是否可能完全没有 Python 之前让我感到惊讶。
简答:不要。你会 运行 遇到问题,uses/reads 你的代码的每个人都会 运行 遇到问题,不值得你花时间来实现它。
长答案:如果绝对必要,您可以创建一个 class 来在调用时设置属性的值,否则模仿值的行为。为此,您必须覆盖 all 和 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')