Python 中的静态方法和实例方法

发布于 2024-11-05 04:34:26 字数 306 浏览 0 评论 0原文

我可以将 Python 方法同时定义为静态方法和实例方法吗?像这样:

class C(object):
    @staticmethod
    def a(self, arg1):
        if self:
            blah
        blah

这样我就可以用两者来调用它:

C.a(arg1)
C().a(arg1)

目的是能够运行两组逻辑。如果作为实例方法访问,它将利用实例变量并执行某些操作。如果作为静态方法访问,则无需。

Can I define a Python method to be both static and instance at the same time? Something like:

class C(object):
    @staticmethod
    def a(self, arg1):
        if self:
            blah
        blah

So that I can call it with both:

C.a(arg1)
C().a(arg1)

The intent is to be able to run two sets of logics. If accessed as an instance method, it would make use of instance variables and do stuff. If access as a static method, it will do without.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

放赐 2024-11-12 04:34:28
import functools

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

  def __get__(self, instance, owner):
    return functools.partial(self.func, instance)

class C(object):
  @static_or_instance
  def a(self, arg):
    if self is None:
      print "called without self:", arg
    else:
      print "called with self:", arg

C.a(42)
C().a(3)
import functools

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

  def __get__(self, instance, owner):
    return functools.partial(self.func, instance)

class C(object):
  @static_or_instance
  def a(self, arg):
    if self is None:
      print "called without self:", arg
    else:
      print "called with self:", arg

C.a(42)
C().a(3)
白馒头 2024-11-12 04:34:28

formencode 有一个 classinstancemethod 装饰器,它可以做你想要的事情。它要求该方法有 2 个参数(selfcls,其中之一可以根据调用上下文传递 None

Lifted来自 formencode/declarative.py

class classinstancemethod(object):
    """
    Acts like a class method when called from a class, like an
    instance method when called by an instance.  The method should
    take two arguments, 'self' and 'cls'; one of these will be None
    depending on how the method was called.
    """

    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type=None):
        return _methodwrapper(self.func, obj=obj, type=type)

class _methodwrapper(object):

    def __init__(self, func, obj, type):
        self.func = func
        self.obj = obj
        self.type = type

    def __call__(self, *args, **kw):
        assert not kw.has_key('self') and not kw.has_key('cls'), (
            "You cannot use 'self' or 'cls' arguments to a "
            "classinstancemethod")
        return self.func(*((self.obj, self.type) + args), **kw)

    def __repr__(self):
        if self.obj is None:
            return ('<bound class method %s.%s>'
                    % (self.type.__name__, self.func.func_name))
        else:
            return ('<bound method %s.%s of %r>'
                    % (self.type.__name__, self.func.func_name, self.obj))

示例用法

class A(object):
    data = 5

    @classinstancemethod
    def print_(self=None, cls=None):
        ctx = self or cls
        print ctx.data


>>> A.print_()
5
>>> a = A()
>>> a.data = 4
>>> a.print_()
4

formencode has a classinstancemethod decorator, which does what what you want. It requires the method to have 2 arguments (self and cls, one of them could get passed None depending on calling context)

Lifted from formencode/declarative.py

class classinstancemethod(object):
    """
    Acts like a class method when called from a class, like an
    instance method when called by an instance.  The method should
    take two arguments, 'self' and 'cls'; one of these will be None
    depending on how the method was called.
    """

    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type=None):
        return _methodwrapper(self.func, obj=obj, type=type)

class _methodwrapper(object):

    def __init__(self, func, obj, type):
        self.func = func
        self.obj = obj
        self.type = type

    def __call__(self, *args, **kw):
        assert not kw.has_key('self') and not kw.has_key('cls'), (
            "You cannot use 'self' or 'cls' arguments to a "
            "classinstancemethod")
        return self.func(*((self.obj, self.type) + args), **kw)

    def __repr__(self):
        if self.obj is None:
            return ('<bound class method %s.%s>'
                    % (self.type.__name__, self.func.func_name))
        else:
            return ('<bound method %s.%s of %r>'
                    % (self.type.__name__, self.func.func_name, self.obj))

Sample usage

class A(object):
    data = 5

    @classinstancemethod
    def print_(self=None, cls=None):
        ctx = self or cls
        print ctx.data


>>> A.print_()
5
>>> a = A()
>>> a.data = 4
>>> a.print_()
4
执手闯天涯 2024-11-12 04:34:28

不。如果可以的话,在方法中 self 意味着什么?

No. What would self mean inside the method, if you could do that?

故事还在继续 2024-11-12 04:34:28

如果您删除 a()self 参数,您的代码将正常工作。当您使用 C().a(arg1) 调用它时,该实例将被忽略。

但您希望此方法既作为静态方法又作为接收实例的方法。你不能两全其美。

Your code will work if you remove the self parameter to a(). When you call it with C().a(arg1) the instance is ignored.

But you want this method to work as both a static method and a method that receives an instance. You can't have it both ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文