使用从 class 属性派生的名称动态定义方法?
Dynamically defining methods with names derived from a class attribute?
标题可能不是对我正在尝试做的事情的最好描述,但我不确定如何称呼它。我遇到了各种看似相关的概念,例如 "decorators"、"descriptors" 和 "metaclasses",但我不知道应该进一步研究这些方法中的哪一种(如果有的话)!
给定以下 classes:
class AnimalGreeter(object):
def __init__(self, greeting):
self.greeting = greeting
def greet(self, animal):
print(self.greeting + ", " + animal + "!")
class MyGreeter(AnimalGreeter):
animals = ['dog', 'parrot']
我希望能够像这样使用 MyGreeter
的实例:
greeter = MyGreeter("What's up")
greeter.parrot
# "What's up, parrot!"
实际上,我希望它像我这样定义 MyGreeter
一样运行:
class MyGreeter(AnimalGreeter):
@property
def dog(self):
self.greet('dog')
@property
def parrot(self):
self.greet('parrot')
换句话说,我想使用从 class (MyGreeter
).
最好的方法是什么?非常感谢!
一个简单的方法就是实现 __getattr__()
,例如:
class MyGreeter(AnimalGreeter):
animals = {'dog', 'parrot'}
def __getattr__(self, animal):
if animal in self.animals:
return self.greet(animal)
raise AttributeError("'{}' object unknown animal '{}'".format(type(self).__name__, animal))
>>> greeter = MyGreeter("What's up")
>>> greeter.parrot
What's up, parrot!
>>> greeter.cat
...
AttributeError: 'MyGreeter' object unknown animal 'cat'
标题可能不是对我正在尝试做的事情的最好描述,但我不确定如何称呼它。我遇到了各种看似相关的概念,例如 "decorators"、"descriptors" 和 "metaclasses",但我不知道应该进一步研究这些方法中的哪一种(如果有的话)!
给定以下 classes:
class AnimalGreeter(object):
def __init__(self, greeting):
self.greeting = greeting
def greet(self, animal):
print(self.greeting + ", " + animal + "!")
class MyGreeter(AnimalGreeter):
animals = ['dog', 'parrot']
我希望能够像这样使用 MyGreeter
的实例:
greeter = MyGreeter("What's up")
greeter.parrot
# "What's up, parrot!"
实际上,我希望它像我这样定义 MyGreeter
一样运行:
class MyGreeter(AnimalGreeter):
@property
def dog(self):
self.greet('dog')
@property
def parrot(self):
self.greet('parrot')
换句话说,我想使用从 class (MyGreeter
).
最好的方法是什么?非常感谢!
一个简单的方法就是实现 __getattr__()
,例如:
class MyGreeter(AnimalGreeter):
animals = {'dog', 'parrot'}
def __getattr__(self, animal):
if animal in self.animals:
return self.greet(animal)
raise AttributeError("'{}' object unknown animal '{}'".format(type(self).__name__, animal))
>>> greeter = MyGreeter("What's up")
>>> greeter.parrot
What's up, parrot!
>>> greeter.cat
...
AttributeError: 'MyGreeter' object unknown animal 'cat'