【问题标题】:python: hybrid between regular method and classmethodpython:常规方法和类方法之间的混合
【发布时间】:2013-08-07 09:00:02
【问题描述】:

有时我需要用静态方法编写类, 但是有可能初始化它并保持状态(对象)

类似的东西:

class A:
  @classmethod
  def method(cls_or_self):
    # get reference to object when A().method() or to class when A.method()
    code

我现在拥有的是:

class A:
   def method(self = None, *params): code
   # or
   def method2(self = None, **params): code
   # but what I need is rather normal parameters, not optional and named args:
   def method3(self_or_cls, a, b=1, c=2, *p, **kw): code

请不要写静态方法和类方法之间的区别。我很感兴趣是否存在这样的装饰器(在或多或少的标准库中),而且上面是否适用于 PEP。

【问题讨论】:

  • 您的意思是类方法和常规方法的混合体。

标签: python methods decorator python-decorators class-method


【解决方案1】:

函数和classmethod对象充当descriptors;两者都返回一个包装器,当调用该包装器时,它将依次调用带有额外参数的底层函数。函数和classmethod 对象的行为方式之间的唯一区别在于那个额外的参数

要混合使用这两种方法,请构建您自己的描述符装饰器:

from functools import wraps

class hybridmethod(object):
    def __init__(self, func):
        self.func = func

    def __get__(self, obj, cls):
        context = obj if obj is not None else cls

        @wraps(self.func)
        def hybrid(*args, **kw):
            return self.func(context, *args, **kw)

        # optional, mimic methods some more
        hybrid.__func__ = hybrid.im_func = self.func
        hybrid.__self__ = hybrid.im_self = context

        return hybrid

在这里,我们返回一个包装器,它将使用类或实例作为第一个参数,具体取决于调用描述符 __get__ 方法时可用的内容。

演示:

>>> class Foo(object):
...     @hybridmethod
...     def bar(cls_or_self):
...         print 'Called with cls_or_self={!r}'.format(cls_or_self)
... 
>>> Foo.bar()
Called with cls_or_self=<class '__main__.Foo'>
>>> Foo().bar()
Called with cls_or_self=<__main__.Foo object at 0x1043a4390>

【讨论】:

  • ... 如此快速和惊人,我必须等待接受答案(stackoverflow reqs),但是 classmethod 呢? - 对我来说,上面的装饰器看起来很实用,甚至建议覆盖 clasmethod 或为方法添加第三个标准装饰器。我知道这需要强烈的批评。
  • classmethod 装饰器服务于不同的目标;对其行为模棱两可的方法(根据上下文采取一种或另一种方式)不太pythonic。
猜你喜欢
  • 2013-12-30
  • 2017-05-24
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-30
  • 2022-10-15
  • 2020-10-11
相关资源
最近更新 更多