Rumah > Soal Jawab > teks badan
下面是 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
Sebenarnya, anda akan memahami bahagian ini dengan melakukan eksperimen anda sendiri.
Mari kita mulakan daripada teks asal dan bahagikannya kepada dua perenggan untuk dibincangkan Perenggan pertama berkata:
Apabila objek kaedah contoh dipanggil, fungsi asas (__func__) dipanggil, memasukkan contoh kelas (__self__) di hadapan senarai argumen Contohnya, apabila C ialah kelas yang mengandungi definisi untuk fungsi f(), dan x ialah kejadian C, memanggil x.f(1) bersamaan dengan memanggil C.f(x, 1).
Perenggan pertama artikel asal mengatakan bahawa apabila instance method object
dipanggil, parameter pertama __func__
digantikan dahulu dengan class instance
dan kemudian dipanggil, dan kemudian memberikan contoh:
x.f(1) == C.f(x,1) # x is an instance of C
Kami menggunakan contoh berikut untuk menggambarkan Di sini kami mempunyai kelas Demo
, yang mempunyai fungsi foo
dan fungsi bar
di bawahnya.
Demo
Kategori:
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)
Sebenarnya:
Python untuk foo
akan menjana fungsi am, yang akan dirujuk oleh Demo.foo
.
Apabila kita menulis demo.foo
, Python akan serta-merta mencipta objek kaedah terikat: demo.foo
Objek kaedah ini adalah kaedah terikat untuk mengikat contoh demo
, jadi demo.foo.__self__
akan merujuk kepada demo
dan Python juga akan merekodkan Demo.foo
dalam demo.foo.__func__
.
Jadi apabila demo.foo
ini dipanggil (demo.foo(1,2,3)
), ia sebenarnya akan memanggil demo.foo.__func__
dan menggunakan demo.foo.__self__
(sebenarnya demo
itu sendiri) sebagai parameter pertama.
Jika ditunjukkan menggunakan kelas yang kami tulis, contohnya menjadi:
x.f(1) == C.f(x, 1)
demo.foo(1) == Demo.foo(demo, 1) == demo.foo.__func__(demo.foo.__self__, 1)
Lihat kod:
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__)
Keputusan ujian:
=== 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
Baca perenggan kedua:
Apabila objek kaedah contoh diterbitkan daripada objek kaedah kelas, "contoh kelas" yang disimpan dalam diri sebenarnya akan menjadi kelas itu sendiri, supaya memanggil sama ada x.f(1) atau C.f(1) adalah bersamaan dengan memanggil f(C,1) dengan f ialah fungsi asas.
Idea utama perenggan kedua ialah apabila objek kaedah contoh datang daripada objek kaedah kelas, self
contoh kelas yang wujud dalam akan menjadi kelas sendiri, dan kemudian Contoh lain:
x.f(1) == C.f(1) == f(C,1) # x is an instance of C
Kami juga menggunakan contoh untuk menggambarkan:
Python akan menjana Demo.bar
untuk bar, iaitu objek kaedah terikat daripada objek kaedah kelas Pada asalnya, Demo.bar
adalah seperti Demo.foo
Ia juga merupakan fungsi Python umum, tetapi melalui penghias (@classmethod
penghias), ia menjadi objek kaedah terikat Jika anda ingin memerhati fungsi umum asal, anda hanya boleh melihatnya dalam Demo.bar.__func__
. ia terikat Demo
kelas, jadi Demo.bar.__self__
akan merujuk kepada kelas Demo
.
Jadi apabila Demo.bar
dipanggil (Demo.bar(1)
), dia sebenarnya akan memanggil Demo.bar.__func__
dan menggunakan Demo.bar.__self__
(sebenarnya Demo
dirinya) sebagai parameter pertama.
Jika ditunjukkan menggunakan kelas yang kami tulis, contohnya menjadi:
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)
Kod ujian:
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))
Keputusan ujian:
=== 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,)
Kesimpulan:
Dalam Python3, terdapat dua jenis fungsi dalam kelas, satu ialah objek fungsi umum, dan satu lagi ialah objek kaedah terikat
Kaedah instance ialah objek kaedah yang terdiri daripada fungsi umum yang terikat pada contoh, dan mehtod kelas ialah objek kaedah yang terdiri daripada fungsi umum yang terikat kepada kelas
kaedah terikat dipanggil, ia sebenarnya memanggil fungsi asal (dirakam dalam __func__
), tetapi objek terikat akan digunakan sebagai parameter pertama (dirakam dalam __self__
) .
Rujukan:
Perbezaan antara kaedah dan fungsi
Perbezaan cara untuk mencipta objek kaedah contoh dalam 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)