__getattr__ 用于静态/类变量

新手上路,请多包涵

我有一个类:

 class MyClass:
     Foo = 1
     Bar = 2

每当调用 MyClass.FooMyClass.Bar 时,我需要在返回值之前调用自定义方法。在 Python 中有可能吗?我知道如果我创建该类的一个实例并且我可以定义我自己的 __getattr__ 方法是可能的。但是我的场景涉及使用此类而不创建它的任何实例。

我还需要一个自定义 __str__ 调用 str(MyClass.Foo) 时调用的方法。 Python 是否提供这样的选项?

原文由 Tuxdude 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 671
2 个回答

__getattr__()__str__() 一个对象在它的类中找到,所以如果你想为一个类定制这些东西,你需要类的类。一个元类。

 class FooType(type):
    def _foo_func(cls):
        return 'foo!'

    def _bar_func(cls):
        return 'bar!'

    def __getattr__(cls, key):
        if key == 'Foo':
            return cls._foo_func()
        elif key == 'Bar':
            return cls._bar_func()
        raise AttributeError(key)

    def __str__(cls):
        return 'custom str for %s' % (cls.__name__,)

class MyClass:
    __metaclass__ = FooType

# # in python 3:
# class MyClass(metaclass=FooType):
#     pass

print(MyClass.Foo)
print(MyClass.Bar)
print(str(MyClass))

印刷:

 foo!
bar!
custom str for MyClass

不,对象不能拦截对其属性之一进行字符串化的请求。为属性返回的对象必须定义自己的 __str__() 行为。

原文由 Matt Anderson 发布,翻译遵循 CC BY-SA 4.0 许可协议

(我知道这是一个老问题,但由于所有其他答案都使用元类……)

您可以使用以下简单的 classproperty 描述符:

 class classproperty(object):
    """ @classmethod+@property """
    def __init__(self, f):
        self.f = classmethod(f)
    def __get__(self, *a):
        return self.f.__get__(*a)()

像这样使用它:

 class MyClass(object):

     @classproperty
     def Foo(cls):
        do_something()
        return 1

     @classproperty
     def Bar(cls):
        do_something_else()
        return 2

原文由 shx2 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题