Maison > Questions et réponses > le corps du texte
下面是 Python 3.x language reference 中的一段话,大意是理解的,不过写不出一个这样的示例,求大神给个与这段话一致的示例:
When an instance method object is derived from a class method object, the “class instance” stored in self will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
黄舟2017-04-17 17:55:52
En fait, vous comprendrez cette partie en faisant vos propres expériences.
Partons du texte original et divisons-le en deux paragraphes pour en discuter. Le premier paragraphe dit :
Lorsqu'un objet méthode d'instance est appelé, la fonction sous-jacente (__func__) est appelée, en insérant l'instance de classe (__self__) devant la liste d'arguments. Par exemple, lorsque C est une classe qui contient une définition pour. une fonction f(), et x est une instance de C, appeler x.f(1) équivaut à appeler C.f(x, 1).
Le premier paragraphe de l'article original dit que lorsqu'un instance method object
est appelé, le premier paramètre de __func__
est d'abord substitué dans class instance
puis appelé, puis donne un exemple :
x.f(1) == C.f(x,1) # x is an instance of C
Nous utilisons l'exemple suivant pour illustrer. Ici, nous avons une classe Demo
, qui a une fonction foo
et une fonction bar
en dessous.
Demo
Catégorie :
class Demo:
def foo(self, *args):
return 'Call foo by instance' + repr(self) + 'with args' + repr(args)
@classmethod
def bar(cls, *args):
return 'Call bar by class ' + repr(cls) + 'with args' + repr(args)
En fait :
Python pour foo
générera une fonction générale, qui sera référencée par Demo.foo
.
Lorsque nous écrivons demo.foo
, Python créera instantanément un objet méthode lié : demo.foo
Cet objet méthode est une méthode liée. À quoi est-il lié ? pour lier l'instance demo
, donc demo.foo.__self__
fera référence à demo
, et Python enregistrera également Demo.foo
dans demo.foo.__func__
.
Ainsi, lorsque ce demo.foo
est appelé (demo.foo(1,2,3)
), il appellera en fait demo.foo.__func__
et utilisera demo.foo.__self__
(en fait demo
lui-même) comme premier paramètre.
S'il est montré en utilisant la classe que nous avons écrite, son exemple devient :
x.f(1) == C.f(x, 1)
demo.foo(1) == Demo.foo(demo, 1) == demo.foo.__func__(demo.foo.__self__, 1)
Regardez le code :
demo = Demo()
print('=== Demo start ===\n')
print('demo.foo', ':', demo.foo)
print(' [type ] ', type(demo.foo))
print(' [demo.foo.__self__] ', demo.foo.__self__)
print(' [demo.foo.__func__] ', demo.foo.__func__)
print(' [demo.foo(1,2,3) ] ', demo.foo(1,2,3))
print()
print('Demo.foo', ':', Demo.foo)
print(' [type ] ', type(Demo.foo))
print(' [Demo.foo(demo, 1,2,3)] ', Demo.foo(demo, 1,2,3))
print()
print('demo.foo.__func__', ':', demo.foo.__func__,)
print(' [type ] ', type(demo.foo.__func__))
print(' [demo.foo.__func__(demo, 1,2,3)] ', demo.foo.__func__(demo, 1,2,3))
print()
print('Demo.foo is demo.foo.__func__ --> ', Demo.foo is demo.foo.__func__)
Résultats des tests :
=== Demo start ===
demo.foo : <bound method Demo.foo of <__main__.Demo object at 0x7f413db47fd0>>
[type ] <class 'method'>
[demo.foo.__self__] <__main__.Demo object at 0x7f413db47fd0>
[demo.foo.__func__] <function Demo.foo at 0x7f413db41840>
[demo.foo(1,2,3) ] Call foo by instance<__main__.Demo object at 0x7f413db47fd0>with args(1, 2, 3)
Demo.foo : <function Demo.foo at 0x7f413db41840>
[type ] <class 'function'>
[Demo.foo(demo, 1,2,3)] Call foo by instance<__main__.Demo object at 0x7f413db47fd0>with args(1, 2, 3)
demo.foo.__func__ : <function Demo.foo at 0x7f413db41840>
[type ] <class 'function'>
[demo.foo.__func__(demo, 1,2,3)] Call foo by instance<__main__.Demo object at 0x7f413db47fd0>with args(1, 2, 3)
Demo.foo is demo.foo.__func__ --> True
Lisez le deuxième paragraphe :
Lorsqu'un objet méthode d'instance est dérivé d'un objet méthode de classe, « l'instance de classe » stockée dans self sera en fait la classe elle-même, de sorte qu'appeler x.f(1) ou C.f(1) équivaut à appelant f(C,1) où f est la fonction sous-jacente.
L'idée principale du deuxième paragraphe est que lorsque l'objet méthode d'instance provient de l'objet méthode de classe, la self
instance de classe qui existe dans sera la classe lui-même, puis un autre exemple :
x.f(1) == C.f(1) == f(C,1) # x is an instance of C
Nous utilisons également des exemples pour illustrer :
Python générera Demo.bar
pour bar, qui est un objet de méthode lié à partir de objet de méthode de classe À l'origine, Demo.bar
est exactement comme Demo.foo
Il. est également une fonction Python générale, mais grâce au décorateur (@classmethod
décorateur), elle devient un objet de méthode lié. Si vous souhaitez observer la fonction générale d'origine, vous ne pouvez la voir que dans Demo.bar.__func__
. il est lié à la Demo
classe, donc Demo.bar.__self__
fera référence à la Demo
classe.
Ainsi, lorsque Demo.bar
est appelé (Demo.bar(1)
), il appellera en fait Demo.bar.__func__
et utilisera Demo.bar.__self__
(en fait Demo
lui-même) comme premier paramètre.
S'il est montré en utilisant la classe que nous avons écrite, son exemple devient :
x.f(1) == C.f(1) == f(C, 1)
demo.bar(1) == Demo.bar(1) == Demo.bar.__func__(Demo, 1) == Demo.bar.__func__(Demo.bar.__self__, 1)
Code de test :
demo = Demo()
print('=== Demo start ===\n')
print('Demo.bar', ':', Demo.bar)
print(' [type ] ', type(Demo.bar))
print(' [Demo.bar.__self__] ', Demo.bar.__self__)
print(' [Demo.bar.__func__] ', Demo.bar.__func__)
print(' [Demo.bar(1,2,3) ] ', Demo.bar(1,2,3))
print()
print('Demo.bar(1) ', Demo.bar(1))
print('demo.bar(1) ', demo.bar(1))
print('Demo.bar.__func__(Demo, 1)', Demo.bar.__func__(Demo, 1))
Résultats des tests :
=== Demo start ===
Demo.bar : <bound method type.bar of <class '__main__.Demo'>>
[type ] <class 'method'>
[Demo.bar.__self__] <class '__main__.Demo'>
[Demo.bar.__func__] <function Demo.bar at 0x7f413db41950>
[Demo.bar(1,2,3) ] Call bar by class <class '__main__.Demo'>with args(1, 2, 3)
Demo.bar(1) Call bar by class <class '__main__.Demo'>with args(1,)
demo.bar(1) Call bar by class <class '__main__.Demo'>with args(1,)
Demo.bar.__func__(Demo, 1) Call bar by class <class '__main__.Demo'>with args(1,)
Conclusion :
En Python3, il existe deux types de fonctions en classe, l'une est un objet de fonction générale et l'autre est un objet de méthode lié
La méthode instance est un objet méthode composé d'une fonction générale liée à une instance, et la classe mehtod est un objet méthode composé d'une fonction générale liée à une classe
liée est appelée, elle appelle en fait la fonction d'origine (enregistrée dans __func__
), mais l'objet lié sera utilisé comme premier paramètre (enregistré dans __self__
).
Références :
Différence entre les méthodes et les fonctions
Différence pour créer un objet méthode d'instance en Python
大家讲道理2017-04-17 17:55:52
# -*- coding: utf-8 -*-
class Parent:
@classmethod
# 这里就相当于是f
def foo(cls, arg):
print("foo called, " + str(cls) + " " + str(arg))
class Child(Parent):
pass
# 创建一个子类的实例
a = Child()
# 调用类方法,可见将对象传递给类方法时,会调用类方法,并且自动绑定了类
a.foo(1)
# 结果和上述一样
Child.foo(1)