__getattr__ 用于静态/类变量

问题描述 投票:0回答:5

我有一个类:

class MyClass:
     Foo = 1
     Bar = 2

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

我还需要一个自定义 __getattr__ 方法,以便在调用 __str__ 时调用。 Python 是否提供这样的选项?

python class-method getattr
5个回答
93
投票
对象的

str(MyClass.Foo)__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 行为。


21
投票

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

您可以使用以下简单的__str__()描述符:

classproperty

像这样使用它:

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

12
投票

首先,您需要创建一个元类,并在其上定义 class MyClass(object): @classproperty def Foo(cls): do_something() return 1 @classproperty def Bar(cls): do_something_else() return 2

__getattr__()

第二个,没有。调用 class MyMetaclass(type): def __getattr__(self, name): return '%s result' % name class MyClass(object): __metaclass__ = MyMetaclass print MyClass.Foo 会调用 str(MyClass.Foo),因此您需要为 MyClass.Foo.__str__() 返回适当的类型。


9
投票

很惊讶没有人指出这个:

MyClass.Foo

作品:

class FooType(type):
    @property
    def Foo(cls):
        return "foo!"

    @property
    def Bar(cls):
        return "bar!"

class MyClass(metaclass=FooType):
    pass

(对于 Python 2.x,将 >>> MyClass.Foo 'foo!' >>> MyClass.Bar 'bar!' 的定义更改为:

MyClass

)

其他答案所说的 class MyClass(object): __metaclass__ = FooType 对这个解决方案适用:它必须在实际返回的类型上实现。


1
投票

根据情况我使用这个模式

str

然后导入并使用它。

class _TheRealClass:
    def __getattr__(self, attr):
       pass

LooksLikeAClass = _TheRealClass()

这避免了元类的使用,并处理了一些用例。

© www.soinside.com 2019 - 2024. All rights reserved.