代码之家  ›  专栏  ›  技术社区  ›  Amit

Python用magic方法获取任意静态方法[duplicate]

  •  0
  • Amit  · 技术社区  · 6 年前

    我有这样一门课:

    class MyClass:
         Foo = 1
         Bar = 2
    

    无论何时 MyClass.Foo MyClass.Bar 调用时,我需要在返回值之前调用一个自定义方法。在Python中可能吗?我知道这是可能的,如果我创建一个类的实例,我可以定义我自己的 __getattr__ 方法。但是我的scnenario涉及使用这个类本身,而不创建它的任何实例。

    __str__ str(MyClass.Foo) 已调用。Python提供了这样的选项吗?

    0 回复  |  直到 12 年前
        1
  •  79
  •   Aran-Fey Kevin    7 年前

    __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
    

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

        2
  •  16
  •   shx2    10 年前

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

    您可以使用以下简单的 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
    
        3
  •  10
  •   Ignacio Vazquez-Abrams    15 年前

    __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

        4
  •  7
  •   xaxxon    6 年前

    没人指出这一点:

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

    MyClass 收件人:

    class MyClass(object):
        __metaclass__ = FooType
    

    )

    其他答案怎么说 str

        5
  •  0
  •   geckos    7 年前

    视情况而定,我使用这种模式

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

    然后导入并使用它。

    from foo import LooksLikeAClass
    LooksLikeAClass.some_attribute