У меня есть класс как:
class MyClass:
Foo = 1
Bar = 2
Каждый раз, когда MyClass.Foo
или MyClass.Bar
вызывается, мне нужен пользовательский метод, который будет вызван, прежде чем значение будет возвращено. Действительно ли это возможно в Python? Я знаю, что возможно, если я создаю экземпляр класса, и я могу определить свое собственное __getattr__
метод. Но мой scnenario включает использование этого класса как такового, не создавая экземпляра его.
Также мне нужно пользовательское __str__
метод, который будет вызван, когда str(MyClass.Foo)
вызывается. Python предоставляет такую возможность?
__ 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 __ ()
.
Для первого вам нужно создать метакласс и определить __ 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
.