__getAttr __用于静态/类变量

发布于 2025-02-01 08:35:02 字数 375 浏览 1 评论 0原文

我有一个类似的类:

class MyClass:
     Foo = 1
     Bar = 2

每当myClass.foomyClass.bar被调用时,我都需要一种自定义方法才能在返回该值之前被调用。在Python中有可能吗?我知道,如果我创建一个类的实例,我可以定义自己的__ getAttr __方法。但是我的scnenario涉及使用此类而没有创建任何实例。

另外,当调用str(myClass.foo)时,我需要调用一个自定义__ str __方法。 Python是否提供了这样的选择?

I have a class like:

class MyClass:
     Foo = 1
     Bar = 2

Whenever MyClass.Foo or MyClass.Bar is invoked, I need a custom method to be invoked before the value is returned. Is it possible in Python? I know it is possible if I create an instance of the class and I can define my own __getattr__ method. But my scnenario involves using this class as such without creating any instance of it.

Also I need a custom __str__ method to be invoked when str(MyClass.Foo) is invoked. Does Python provide such an option?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

纸伞微斜 2025-02-08 08:35:02

__ 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):
    pass

# # in python 2:
# class MyClass:
#    __metaclass__ = FooType


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

打印:

foo!
bar!
custom str for MyClass

不,一个对象无法拦截一个符合其属性之一的请求。返回的属性对象必须定义其自己的__ str __()行为。

更新了Python 3.x默认实现的2023-02-20(Python 2作为评论)。

__getattr__() and __str__() for an object are found on its class, so if you want to customize those things for a class, you need the class-of-a-class. A metaclass.

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):
    pass

# # in python 2:
# class MyClass:
#    __metaclass__ = FooType


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

printing:

foo!
bar!
custom str for MyClass

And no, an object can't intercept a request for a stringifying one of its attributes. The object returned for the attribute must define its own __str__() behavior.

Updated 2023-02-20 for Python 3.x default implementation (python 2 as a comment).

蓝眸 2025-02-08 08:35:02

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

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

(I know this is an old question, but since all the other answers use a metaclass...)

You can use the following simple classproperty descriptor:

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

Use it like:

class MyClass(object):

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

     @classproperty
     def Bar(cls):
        do_something_else()
        return 2
温柔女人霸气范 2025-02-08 08:35:02

首先,您需要创建一个元素,并在其中定义__ getAttr __()

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

class MyClass(object):
  __metaclass__ = MyMetaclass

print MyClass.Foo

第二,不。调用str(myClass.foo) indokes myClass.foo .__ str __(),因此您需要返回适当的类型myClass.foo

For the first, you'll need to create a metaclass, and define __getattr__() on that.

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

class MyClass(object):
  __metaclass__ = MyMetaclass

print MyClass.Foo

For the second, no. Calling str(MyClass.Foo) invokes MyClass.Foo.__str__(), so you'll need to return an appropriate type for MyClass.Foo.

兮颜 2025-02-08 08:35:02

,没有人指出这个

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!'

:(对于python 2.x,更改myClass的定义到

class MyClass(object):
    __metaclass__ = FooType

:)

其他答案对str对此解决方案的含义为:必须在实际返回的类型上实现。

Surprised no one pointed this one out:

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

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

class MyClass(metaclass=FooType):
    pass

Works:

>>> MyClass.Foo
'foo!'
>>> MyClass.Bar
'bar!'

(for Python 2.x, change definition of MyClass to:

class MyClass(object):
    __metaclass__ = FooType

)

What the other answers say about str holds true for this solution: It must be implemented on the type actually returned.

夜声 2025-02-08 08:35:02

根据情况,我使用此模式

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

LooksLikeAClass = _TheRealClass()

,然后您将其导入并使用它。

from foo import LooksLikeAClass
LooksLikeAClass.some_attribute

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

Depending on the case I use this pattern

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

LooksLikeAClass = _TheRealClass()

Then you import and use it.

from foo import LooksLikeAClass
LooksLikeAClass.some_attribute

This avoid use of metaclass, and handle some use cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文