简体   繁体   English

从python 3中的类对象调用成员方法

[英]Calling member methods from class object in python 3

I have this bit of code: 我有这段代码:

class ABC:
    def test():
        print('Hi there')

ABC.test()

Which outputs: 哪个输出:

Hi there

Whereas this fails: 鉴于此失败:

ABC().test()
TypeError: test() takes 0 positional arguments but 1 was given
# Makes sense

We know that when we invoke a classmethod like <classname>.<methodname>() , the class is implicitly passed as an argument to it, but test here takes no arguments. 我们知道,当我们调用classmethod<classname>.<methodname>()该类隐含作为参数传递给它,但test这里不带任何参数。

Why don't we see a TypeError because of the unexpected argument? 为什么由于意外的参数而看不到TypeError Isn't the class passed as an argument to test ? 该类不是通过传递给test的参数吗?

Nothing is passed to test() because functions do not bind to anything when accessed to a class. 什么都不会传递给test()因为在访问类时函数不会绑定任何东西。 It remains unbound , you get the original function: 它保持未绑定状态 ,您将获得原始功能:

>>> class ABC:
...     def test():
...         print('Hi there')
...
>>> ABC.test
<function ABC.test at 0x1082706c0>

You can call functions directly, provided you pass in the right number of arguments. 只要传入正确数量的参数,就可以直接调用函数。 Here that is 0, so ABC.test() succeeds. 此处为0,因此ABC.test()成功。

It is not a classmethod , that would require decorating it with @classmethod (or otherwise producing a classmethod object and storing it as an attribute of the class), at which point accessing the attribute binds the function to the class object, producing a bound method : 它不是classmethod ,它需要使用@classmethod装饰(或生成classmethod对象并将其存储为类的属性),这时访问属性会将函数绑定到class对象,从而生成绑定method

>>> class ABC:
...     @classmethod
...     def test():
...         print('Hi there')
...
>>> ABC.test
<bound method ABC.test of <class '__main__.ABC'>>

Calling this results in an exception: 调用此方法将导致异常:

>>> ABC.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes 0 positional arguments but 1 was given

Functions can be bound too, but only when accessed on an instance of the class. 也可以绑定函数,但只能在类的实例上访问时。 Both function and classmethod objects implement the descriptor protocol , and accessing attributes on classes and on instances will trigger the __get__ method on descriptors. function对象和classmethod对象都实现描述符协议 ,访问类和实例上的属性将触发描述符的__get__方法。 But only classmethod objects return a bound method in that case, functions just return themselves. 但是在这种情况下,只有classmethod对象会返回绑定方法,而函数只会返回自身。

Specifically, the descriptor __get__ method is passed None for the first argument, the object to bind to, when the attribute access is on a class, and the instance when accessed on the instance. 具体地, 描述符__get__方法被传递None为第一个参数,以结合,当属性访问是一类的对象,并且实例在实例时访问。 classmethod().__get__() ignores the instance argument and produces a method object that binds to the second argument ( owner ). classmethod().__get__()忽略实例参数,并生成绑定到第二个参数( owner )的方法对象。 Functions return self when the first argument is None , or a method object that binds to the instance otherwise: 当第一个参数为None ,函数将返回self ,否则将返回绑定到实例的方法对象:

>>> def foo(boundto='nothing'):
...     print(f'Bound to {boundto}')
...
>>> foo.__get__('instance', 'owner')()
Bound to instance
>>> foo.__get__(None, 'owner')()
Bound to nothing
>>> classmethod(foo).__get__('instance', 'owner')()
Bound to owner
>>> classmethod(foo).__get__(None, 'owner')()
Bound to owner

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM