为了账号安全,请及时绑定邮箱和手机立即绑定

Python中的类方法差异:绑定、未绑定和静态

Python中的类方法差异:绑定、未绑定和静态

狐的传说 2019-07-09 16:33:14
Python中的类方法差异:绑定、未绑定和静态下面的类方法有什么区别?是一个是静态的,另一个不是静态的吗?class Test(object):   def method_one(self):     print "Called method_one"   def method_two():     print "Called method_two"a_test = Test()a_test.method_one()a_test.method_two()
查看完整描述

3 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

在Python中,定界解束缚方法。

基本上,对成员函数的调用(如method_one),一个有界函数

a_test.method_one()

翻译成

Test.method_one(a_test)

即对未绑定方法的调用。正因为如此,打电话给你的版本method_two将失败TypeError

>>> a_test = Test() >>> a_test.method_two()Traceback (most recent call last):
  File "<stdin>", line 1, in <module>TypeError: method_two() takes no arguments (1 given)

可以使用装饰器更改方法的行为。

class Test(object):
    def method_one(self):
        print "Called method_one"

    @staticmethod
    def method_two():
        print "Called method two"

装饰师告诉内置的默认元类。type(一班中的一班,参见。这个问题)不创建绑定方法method_two.

现在,您可以直接在实例或类上调用静态方法:

>>> a_test = Test()>>> a_test.method_one()Called method_one>>> a_test.method_two()Called method_two>>> Test.method_two()Called method_two


查看完整回答
反对 回复 2019-07-09
?
aluckdog

TA贡献1847条经验 获得超7个赞

一旦您了解了描述符系统的基本知识,Python中的方法就是一件非常简单的事情。想象一下以下课程:

class C(object):
    def foo(self):
        pass

现在让我们看看shell中的类:

>>> C.foo<unbound method C.foo>>>> C.__dict__['foo']<function foo at 0x17d05b0>

如您所见,如果您访问foo属性返回一个未绑定的方法,但是在类存储(Dict)中有一个函数。为什么这么说?这是因为类的类实现了__getattribute__这就解决了描述符。听起来很复杂,但事实并非如此。C.foo与此特殊情况下的代码大致相同:

>>> C.__dict__['foo'].__get__(None, C)<unbound method C.foo>

那是因为函数有一个__get__方法,使它们成为描述符。如果您有一个类的实例,它几乎是相同的,只是None是类实例:

>>> c = C()>>> C.__dict__['foo'].__get__(c, C)<bound method C.foo of <__main__.C object at 0x17bd4d0>>

为什么Python会这么做呢?因为方法对象将函数的第一个参数绑定到类的实例。这就是赛尔夫的来历。有时候你不想让你的类把一个函数变成一个方法,这就是staticmethod发挥作用:

 class C(object):
  @staticmethod
  def foo():
   pass

这个staticmethod装饰器封装类并实现一个虚拟的__get__它将包装的函数作为函数而不是方法返回:

>>> C.__dict__['foo'].__get__(None, C)<function foo at 0x17d0c30>

希望这就解释了。


查看完整回答
反对 回复 2019-07-09
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

>>> class Class(object):

...     def __init__(self):

...         self.i = 0

...     def instance_method(self):

...         self.i += 1

...         print self.i

...     c = 0

...     @classmethod

...     def class_method(cls):

...         cls.c += 1

...         print cls.c

...     @staticmethod

...     def static_method(s):

...         s += 1

...         print s

... 

>>> a = Class()

>>> a.class_method()

1

>>> Class.class_method()    # The class shares this value across instances

2

>>> a.instance_method()

1

>>> Class.instance_method() # The class cannot use an instance method

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: unbound method instance_method() must be called with Class instance as first argument (got nothing instead)

>>> Class.instance_method(a)

2

>>> b = 0

>>> a.static_method(b)

1

>>> a.static_method(a.c) # Static method does not have direct access to 

>>>                      # class or instance properties.

3

>>> Class.c        # a.c above was passed by value and not by reference.

2

>>> a.c

2

>>> a.c = 5        # The connection between the instance

>>> Class.c        # and its class is weak as seen here.

2

>>> Class.class_method()

3

>>> a.c

5


查看完整回答
反对 回复 2019-07-09
  • 3 回答
  • 0 关注
  • 506 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信