71

私は次のようなクラスを持っています:

class MyClass:
     Foo = 1
     Bar = 2

MyClass.FooorMyClass.Barが呼び出されるたびに、値が返される前にカスタム メソッドを呼び出す必要があります。Pythonで可能ですか?__getattr__クラスのインスタンスを作成し、独自のメソッドを定義できれば、それが可能であることはわかっています。しかし、私のシナリオでは、このクラスをインスタンスを作成せずにそのまま使用します。

また、呼び出されたときに呼び出されるカスタム__str__メソッドが必要str(MyClass.Foo)です。Python はそのようなオプションを提供していますか?

4

5 に答える 5

86

__getattr__()および__str__()オブジェクトの場合はそのクラスにあるため、クラス用にこれらのものをカスタマイズする場合は、class-of-a-class が必要です。メタクラス。

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

いいえ、オブジェクトは、その属性の 1 つを文字列化する要求を傍受できません。属性に対して返されるオブジェクトは、独自の__str__()動作を定義する必要があります。

于 2010-07-01T06:24:20.020 に答える
19

(これは古い質問であることは知っていますが、他のすべての回答はメタクラスを使用しているため...)

次の単純な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
于 2014-03-29T09:43:06.280 に答える
12

最初に、メタクラスを作成し、それを定義する必要があります__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

于 2010-07-01T06:26:07.007 に答える