__python中静态/类变量的getattr\uuuuu

__python中静态/类变量的getattr\uuuuu,python,class-method,getattr,Python,Class Method,Getattr,我有一门课,像: class MyClass: Foo = 1 Bar = 2 每当调用MyClass.Foo或MyClass.Bar时,我需要在返回值之前调用一个自定义方法。在Python中可能吗?我知道如果我创建一个类的实例,并且我可以定义自己的\uu getattr\uuu方法,这是可能的。但是我的scnenario涉及到这样使用这个类,而不创建它的任何实例 此外,我还需要一个自定义的\uuu str\uu方法,以便在调用str(MyClass.Foo)时调用。Pyt

我有一门课,像:

class MyClass:
     Foo = 1
     Bar = 2
每当调用
MyClass.Foo
MyClass.Bar
时,我需要在返回值之前调用一个自定义方法。在Python中可能吗?我知道如果我创建一个类的实例,并且我可以定义自己的
\uu getattr\uuu
方法,这是可能的。但是我的scnenario涉及到这样使用这个类,而不创建它的任何实例

此外,我还需要一个自定义的
\uuu str\uu
方法,以便在调用
str(MyClass.Foo)
时调用。Python提供了这样的选项吗?

\uuuu getattr\uuuuuuuuuuuuuuuuuo()
\uuuuuuu str\uuuuuuuuuuuuuuuuuuuuo()
对象都可以在其类中找到,因此如果您想为类定制这些东西,您需要类中的类。元类

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

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

首先,您需要创建一个元类,并在该元类上定义
\uu getattr\uuuuu()

class MyMetaclass(type):
  def __getattr__(self, name):
    return '%s result' % name

class MyClass(object):
  __metaclass__ = MyMetaclass

print MyClass.Foo

对于第二种情况,no.Calling
str(MyClass.Foo)
会调用
MyClass.Foo.\uu str\uuu()
,因此您需要为
MyClass.Foo

返回一个合适的类型,没有人指出这一点:

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

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

class MyClass(metaclass=FooType):
    pass
作品:

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

class MyClass(object):
    __metaclass__ = FooType
)

其他答案对
str
的解释适用于此解决方案:它必须在实际返回的类型上实现。

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

您可以使用以下简单的
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

根据具体情况,我使用这种模式

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

LooksLikeAClass = _TheRealClass()
然后导入并使用它

from foo import LooksLikeAClass
LooksLikeAClass.some_attribute

这样可以避免使用元类,并处理一些用例。

谢谢Ignacio和Matt。我想现在我明白了类(而不是实例)创建是如何工作的,而且我认为所需的str行为很难实现。我认为元类应该满足我的要求如果您总是得到
AttributeError
检查另一个答案,它有python3的语法(这个例子似乎是python2)测试了这个例子,它只在python2.x中对我有效。将打印更改为函数后,Python3.2给了我一个“AttributeError:type对象'MyClass'没有属性'Foo'”错误。有什么建议吗?@CyberED::“读取类定义时,如果在类定义中的基之后传递了可调用的
元类
关键字参数,则将调用给定的可调用参数,而不是
type()
“无法等待…”。。。。在谷歌搜索和测试之后:这个例子是针对Python2.x的。在Python3.x中,您需要:class MyClass(metaclass=MyMetaclass):pass这只有在您事先知道属性名称的情况下才有帮助。如果您从文件中读取它们并需要动态响应,这将不起作用。虽然我通常会尽量避免发布“谢谢”,但我现在真的需要发布“谢谢”:谢谢!