【问题标题】:Assigning attributes to class methods为类方法分配属性
【发布时间】:2019-12-03 01:29:09
【问题描述】:

假设我有一个充当方法容器的类。我有一个在字典中列出这些方法的配置文件。在一个程序中,我想从配置中导入字典并对其进行迭代,同时调用该类中的方法。

问题是,如果方法是一种,我需要以一种方式处理它们,如果是另一种方式,我需要以另一种方式处理它们。所以容器类看起来像:

class Circus(object):
    def clown(self):
        return print("*HONK*")

    def lion(self):
        return print("roar")

    def __call__(self):
        setattr(clown, 'isFunny', True)
        setattr(lion, 'isFunny', False)

我的配置文件:

circus = {
    'funny_thing': Circus.clown,
    'unfunny_thing': Circus.lion
}

还有实际的脚本:

for item in circus.items():
    if item[1].isFunny == True:
        item()

我已经忘记了我尝试过的所有内容,但它包括将其分为两个类并在每个类中创建一个 isFunny() 方法(返回真或假),将事物分配给类 __dict__,放置 setattr()在不同的地方,使用 __init__、@staticmethod@classmethod

我期望的是一个简单的*HONK*,但大多数情况下都会输出一个AttributeError: 'function' object has no attribute 'isFunny'

我做错了什么?


作为参考,我尝试过的一些链接:

【问题讨论】:

  • 但是你为什么要将这些属性添加到方法中呢?为什么不将它们添加到 objects 本身,然后所有方法都可以访问它们
  • 这与我在现实生活中的实现方式、配置文件和所有内容有关。截止日期太近了,现在无法重写所有内容,但我愿意学习最佳实践。

标签: python class methods attributes


【解决方案1】:

__call__ 在您调用一个实例时被调用。给定c = Circus()c()c.__call__() 相同。因此,您试图在定义属性之前对其进行检查。此外,在__call__ 方法中,既没有定义clown,也没有定义lion。它们都是类属性,需要按原样使用(即Circus.clownself.clown)。如果要标记方法,直接在class 语句中进行。

class Circus:
    def clown(self):
        print("*HONK*")

    def lion(self):
        print("roar")

    clown.isFunny = True
    lion.isFunny = False

circus = {
    'funny_thing': Circus.clown,
    'unfunny_thing': Circus.lion
}


for item in circus.items():
    if item[1].isFunny:
        item[1]()

但是,请注意item[1]() 仍然是错误的,因为未绑定的方法仍然需要Circus实例 作为其第一个参数。一些建议的修复方法,具体取决于您实际要完成的工作:

  1. 将方法设为类方法或静态方法,这样就不需要额外的参数了。

  2. 在字典中存储绑定方法:

    c = Circus()
    circus = {
        'funny_thing': c.clown,
        'unfunny_thing': c.lion
    }
    

【讨论】:

  • 谢谢,现在看来很明显了!
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 2018-06-24
  • 2022-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
相关资源
最近更新 更多