__ getattr __ для статических / переменных класса в Python

У меня есть класс как:

class MyClass:
     Foo = 1
     Bar = 2

Каждый раз, когда MyClass.Foo или MyClass.Bar вызывается, мне нужен пользовательский метод, который будет вызван, прежде чем значение будет возвращено. Действительно ли это возможно в Python? Я знаю, что возможно, если я создаю экземпляр класса, и я могу определить свое собственное __getattr__ метод. Но мой scnenario включает использование этого класса как такового, не создавая экземпляра его.

Также мне нужно пользовательское __str__ метод, который будет вызван, когда str(MyClass.Foo) вызывается. Python предоставляет такую возможность?

58
задан P̲̳x͓L̳ 29 March 2014 в 09:30
поделиться

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 __ () .

66
ответ дан 24 November 2019 в 18:56
поделиться

Для первого вам нужно создать метакласс и определить __ 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 __ () , поэтому вам нужно будет вернуть соответствующий тип для MyClass.Foo .

10
ответ дан 24 November 2019 в 18:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: