【问题标题】:Python add methods of objects to containing list [duplicate]Python将对象的方法添加到包含列表[重复]
【发布时间】:2021-11-24 17:12:58
【问题描述】:

我有一个包含同一类对象的列表。现在我想让该列表成为一个容器类,它与它包含的对象的所有方法相关,如下面的示例所示。但是由于我有很多方法,我不想再像这样在包含容器类中明确地写下来:

模块 fe.py

class foo:

    def __init__(self,weight,age):
        self.weight = weight
        self.age = age

    def get_weight(self):
        return self.weight

    def get_age(self):
        return self.age

    def multiply(self):
        return self.weight*self.age


class foo_list(list):

    def __init__(self,foo_tuple):
        list.__init__(self,foo_tuple)

    def __getattribute__(self,name):
        return [getattr(x,name)() for x in self]

现在是一个执行示例:

import fe

u=fe.foo_list((fe.foo(1,2),fe.foo(3,4)))
u.multiply
[2, 12]
u.multiply()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable

但是通过这种方式方法属性与结果相关联。但我希望它是一种调用方法,就像在包含的对象中一样

【问题讨论】:

  • 不清楚您的问题到底是什么,请澄清。
  • 现在清楚了吗?
  • 元类本身是不必要的。简单地实现__getattr__ 来拦截未定义的方法调用怎么样? ??? stackoverflow.com/a/3855062/476
  • @deceze 我认为 OP 已经澄清了足够多的问题,可以重新打开它。至少对我来说已经足够清楚了。
  • 感谢有关 getattribute 的提示,我可以按照自己的意愿创建容器类。该属性现在给出结果,但不再可调用。

标签: python list object containers metaclass


【解决方案1】:
def __getattribute__(self,name):
    return [getattr(x,name)() for x in self]

__getattribute__ 返回一个列表,这意味着 u.multiply 只是一个列表;然后你试图打电话。如果你想让这个魔法属性伪装成一个方法,那么__getattribute__ 需要返回一个可调用函数:

def __getattribute__(self, name):
    def f():
        return [getattr(x, name)() for x in self]
    return f

【讨论】:

  • 请注意,每次调用时重新定义函数都会产生开销,如果您打算大量调用这些动态方法,则可能会增加开销,在这种情况下,可能值得使用元类来在启动期间生成一次动态方法。这是一个演示(最初是作为答案编写的,但由于问题已关闭,现在是评论):ideone.com/gL6at2
猜你喜欢
  • 2015-12-04
  • 2020-04-09
  • 2018-07-23
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多