动态生成类的类/静态属性的__getattr__和__getattribute__方法

3
这个问题的答案解释了如何使用元类实现静态/类属性的__getattr__。然而,我想为由type()生成的类实现__getattr____getattribute__,并使事情变得更有趣的是,该类继承了一个具有自定义元类的类,必须正确执行该元类。
class Inherited(metaclass=SomeFancyMetaclass):
    ...

generated_class = type("GeneratedClass", (Inherited,), {})

def __class_getattr__(cls, name):  # __getattr__ for class, not sure how the code shall look exactly like
    return getattr(cls, name)

setattr(generated_class, "__getattr__", __class_getattr__)  # similarly for __getattribute__

问题是:这是否可能,如果可以,该怎么做?有人能提供一个最小的工作示例吗?

你需要在元类(metaclass)上实现__getattr____setattr__方法,然后使用元类来生成类。我相信这样可以完成任务。 - juanpa.arrivillaga
您可以通过以下方式创建生成的类:type(“GeneratedClass”,(Inherited,),{ '__getattr__':your_getattr_impl}),并且your_getattr_impl 应该有一个签名 (self, name)(应使用实例而非cls,因为在使用时将传递类的实例),除非您要在元类级别进行操作。此外,您真的不需要元类来动态创建具有自定义属性的类以用于dunder函数。您究竟想达到什么效果? - metatoaster
@metatoaster 他们正在尝试在元类上实现这些特殊方法,以便与类属性一起使用。 - juanpa.arrivillaga
@juanpa.arrivillaga 我能理解你的观点,但除非有充分的理由来覆盖元类并利用动态类构建,否则这几乎总是过度设计。我的意思是建议OP选择一种技术,除非有充分的理由同时使用两种技术。 - metatoaster
你只需要像使用type(...,...,...)一样使用MyCustomMeta(...,...,...),但是他们必须实际实现MyCustomMeta。我的意思是,这一切可能都有点过头了。为什么要停下来呢... - juanpa.arrivillaga
1个回答

2

只需让你的元类继承自SomeFancyMetaclass,适当实现__getattr__(和__getattribute__),并使用这个元类,而不是调用type来生成你继承的动态类。

虽然你使用了很多不常用的东西,但在方法上没有特殊机制 - 它应该是纯粹的Python -

当然,你没有告诉需要在元类的特殊方法中做什么 - 可能需要进行一些黑魔法操作 - 如果你使用__getattribute__,你必须格外小心,并将所有不关心的属性重定向到super调用,否则,什么都不起作用。

另外,请记住,通过这两种方法可能会自定义属性访问,但不能用于“创建神奇的双下划线方法” - 也就是说:你的类不会因为你的元类__getattribute__生成一个__add__或__dir__方法而自动拥有它们 - 相反,这些方法由Python运行时在特殊槽中固定,并且它们的检查和调用绕过了Python的正常属性查找。

其他方面:

class Inherited(metaclass=SomeFancyMetaclass):
    ...

class MagicAttrsMeta(Inherited.__class__):
    def __getattr__(self, attr):
          if attr in ("flying", "circus", "brian", "king_arthur"):
               return "coconut"
          raise AttributeError()


generated_class = MagicAttrsMeta("GeneratedClass", (Inherited,), {})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接