Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用从类属性派生的名称动态定义方法?_Python_Metaprogramming - Fatal编程技术网

Python 使用从类属性派生的名称动态定义方法?

Python 使用从类属性派生的名称动态定义方法?,python,metaprogramming,Python,Metaprogramming,这个标题可能不是我想做的最好的描述,但我不知道该怎么称呼它。我遇到了各种看似相关的概念,如“装饰器”、“描述符”和“元类”,但我不知道应该进一步研究哪种方法(如果有的话) 鉴于以下类别: class AnimalGreeter(object): def __init__(self, greeting): self.greeting = greeting def greet(self, animal): print(self.greeting +

这个标题可能不是我想做的最好的描述,但我不知道该怎么称呼它。我遇到了各种看似相关的概念,如“装饰器”、“描述符”和“元类”,但我不知道应该进一步研究哪种方法(如果有的话)

鉴于以下类别:

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')
换句话说,我想动态定义方法(
dog()
,等等),其名称来自类(
MyGreeter
)的属性(
animals


最好的方法是什么?非常感谢

一个简单的方法就是实现
\uuu getattr\uuuu()
,例如:

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'

只需实现
\uuu getattr\uuuu(self,animal)
。在这里我无能为力,但我对您的用例感兴趣。你为什么需要这种行为?@FabienP,在我的例子中,
AnimalGreeter
是Django模型,
MyGreeter
是一个自定义的mixin,用于处理具有可配置文件名的图像。我想访问Django模板中的图像URL,但Django的模板系统不允许向实例方法传递参数。因此,我无法在模板中执行与
model.image\u url('large')
等效的操作。但是我可以访问模板中的实例属性,例如,
model.large\u image\u url
@tino:很高兴知道,谢谢你的解释!谢谢这是我遇到的建议之一,但不确定我是否应该担心开销
AnimalGreeter
还有许多其他属性,经常被访问。是否每次访问任何实例属性时都会执行此操作?@tino No No,仅当您访问“不存在”的属性时才会调用
\uuu getattr\uuuu
,也就是说,在抛出AttributeError时才会调用它@拉温,啊,这很有道理。谢谢你的链接和解释!