Bagaimana untuk menggunakan diri dalam Python

WBOY
Lepaskan: 2023-05-17 22:40:48
ke hadapan
1930 orang telah melayarinya

Sebelum memperkenalkan penggunaan diri dalam Python, mari kita perkenalkan dahulu kelas dan kejadian dalam Python
Kami tahu bahawa konsep berorientasikan objek yang paling penting ialah kelas dan contoh adalah templat abstrak perkara seperti pelajar boleh diwakili oleh kelas Pelajar. Instance ialah "objek" khusus yang dibuat berdasarkan kelas Setiap objek mewarisi kaedah yang sama daripada kelas, tetapi datanya mungkin berbeza.
1. Ambil kelas Pelajar sebagai contoh Dalam Python, kelas ditakrifkan seperti berikut:

class Student(object):
    pass
Salin selepas log masuk

(Objek) menunjukkan kelas mana yang diwarisi oleh kelas Objek akan mewarisi.

2 Contoh: Selepas kelas ditakrifkan, anda boleh mencipta tika Pelajar melalui kelas Pelajar Mencipta tika dicapai melalui nama kelas + ():

student = Student()
Salin selepas log masuk

3. Oleh kerana kelas memainkan peranan templat adalah untuk mengisi secara paksa atribut yang kami fikir mesti terikat semasa membuat contoh. Di sini kita menggunakan kaedah __init__, kaedah terbina dalam Python Contohnya, dalam kelas Pelajar, ikat atribut seperti nama dan skor kepadanya:

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
Salin selepas log masuk

Nota di sini: (1), yang. bahagian pertama kaedah __init__ Parameter pertama sentiasa self, yang mewakili kelas yang dicipta sendiri Oleh itu, di dalam kaedah __init__, anda boleh mengikat pelbagai atribut kepada diri sendiri, kerana diri menunjuk kepada contoh yang dibuat itu sendiri. (2) Dengan kaedah __init__, apabila membuat contoh, anda tidak boleh menghantar parameter kosong Anda mesti memasukkan parameter yang sepadan dengan kaedah __init__, tetapi diri tidak perlu dihantar Jurubahasa Python akan pembolehubah Instance diluluskan dalam:

>>>student = Student("Hugh", 99)
>>>student.name
"Hugh"
>>>student.score
99
Salin selepas log masuk

Selain itu, di sini self merujuk kepada kelas itu sendiri dan self.name ialah pembolehubah atribut kelas Student, yang dimiliki oleh kelas Student. Dan name ialah parameter luaran, bukan parameter yang disertakan dengan kelas Student. Oleh itu, self.name = name bermaksud untuk memberikan nilai parameter luaran name kepada pembolehubah atribut kelas Pelajar sendiri self.name.

4 Berbanding dengan nombor biasa, hanya terdapat satu perbezaan apabila mentakrifkan fungsi dalam kelas, iaitu parameter pertama sentiasa pembolehubah contoh kelas itu sendiri. self Dan apabila membuat panggilan, tidak perlu melepasi parameter ini. Selain itu, kaedah kelas (fungsi) tidak berbeza daripada fungsi biasa Anda boleh menggunakan parameter lalai, parameter pembolehubah atau parameter kata kunci (*args ialah parameter berubah, args Apa yang diterima ialah tuple<. 🎜>, **kw ialah parameter kata kunci dan kw menerima dict).

5 Memandangkan contoh kelas

Pelajar sendiri memiliki data ini, maka untuk mengakses data ini, tidak perlu mengaksesnya daripada fungsi luaran, tetapi boleh ditakrifkan secara langsung dalam kelas Pelajar. . Fungsi (kaedah) data, supaya "data" boleh dikapsulkan. Fungsi yang merangkum data ini dikaitkan dengan kelas Pelajar itu sendiri, dan dipanggil kaedah kelas:

class Student(obiect):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print "%s: %s" % (self.name, self.score)
Salin selepas log masuk
>>>student = Student("Hugh", 99)
>>>student.print_score
Hugh: 99
Salin selepas log masuk

Dengan cara ini, apabila kita melihat kelas Pelajar dari luar, kita hanya perlu tahu apa yang diperlukan untuk buat nama dan skor. Cara mencetak ditakrifkan dalam kelas Pelajar

Data dan logik ini dirangkumkan, menjadikannya mudah untuk dipanggil, tetapi anda tidak mengetahui butiran pelaksanaan dalaman.

Jika anda ingin menghalang atribut dalaman daripada diakses secara luaran, anda boleh menambah dua garis bawah

sebelum nama atribut Dalam Python, jika nama pembolehubah bagi suatu contoh bermula dengan , kemudian Ia menjadi pembolehubah persendirian (peribadi), yang hanya boleh diakses secara dalaman dan bukan secara luaran Oleh itu, kami menukar kelas Pelajar:

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score
    def print_score(self):
        print "%s: %s" %(self.__name,self.__score)
Salin selepas log masuk

Selepas pengubahsuaian, tiada perubahan untuk kod luaran. tetapi Pembolehubah Instance

dan pembolehubah instance .__name tidak lagi boleh diakses dari luar: .__score

>>> student = Student(&#39;Hugh&#39;, 99)
>>> student.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: &#39;Student&#39; object has no attribute &#39;__name&#39;
Salin selepas log masuk

Ini memastikan kod luaran tidak boleh mengubah suai keadaan dalaman objek sesuka hati, supaya melalui perlindungan sekatan akses, kod itu lebih mantap.

Tetapi bagaimana jika kod luaran ingin mendapatkan nama dan markah? Anda boleh menambah kaedah seperti get_name dan get_score pada kelas Pelajar:

class Student(object):
    ...

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score
Salin selepas log masuk

Bagaimana jika anda mahu membenarkan kod luaran mengubah suai skor? Anda boleh menambah kaedah set_score pada kelas Pelajar:

class Student(object):
    ...

    def set_score(self, score):
        self.__score = score
Salin selepas log masuk

Perlu diingat bahawa dalam Python, nama pembolehubah adalah serupa dengan

, iaitu nama yang bermula dengan garis bawah berganda dan berakhir dengan dua kali ganda. garis bawah ialah pembolehubah khas. __xxx____name__Kadangkala, anda akan melihat nama pembolehubah contoh bermula dengan garis bawah, seperti _name Pembolehubah contoh sedemikian boleh diakses secara luaran, bagaimanapun, mengikut konvensyen, apabila anda melihat pembolehubah tersebut Apabila, ia bermakna, ". Walaupun saya boleh diakses, sila anggap saya sebagai pembolehubah peribadi dan jangan mengaksesnya sesuka hati." Satu lagi faedah pengkapsulan __score__

ialah anda boleh menambah kaedah baharu

ke kelas Pelajar pada bila-bila masa, seperti:

:

class Student(object):
    ...
    def get_grade(self):
        if self.score >= 90:
            return &#39;A&#39;
        elif self.score >= 60:
            return &#39;B&#39;
        else:
            return &#39;C&#39;
Salin selepas log masuk
Begitu juga, get_grade kaedah boleh terus Dipanggil pada pembolehubah contoh, tidak perlu mengetahui butiran pelaksanaan dalaman:

>>> student.get_grade()
&#39;A&#39;
Salin selepas log masuk

6、self的仔细用法
(1)、self代表类的实例,而非类。

class Test:
    def ppr(self):
        print(self)
        print(self.__class__)

t = Test()
t.ppr()
执行结果:
<__main__.Test object at 0x000000000284E080>
<class &#39;__main__.Test&#39;>
Salin selepas log masuk

从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。
注意:把self换成this,结果也一样,但Python中最好用约定俗成的self。
(2)、self可以不写吗?
在Python解释器的内部,当我们调用t.ppr()时,实际上Python解释成Test.ppr(t),也就是把self替换成了类的实例。

class Test:
    def ppr():
        print(self)

t = Test()
t.ppr()
Salin selepas log masuk

运行结果如下:

Traceback (most recent call last):
File "cl.py", line 6, in
t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given

运行时提醒错误如下:ppr在定义时没有参数,但是我们运行时强行传了一个参数。

由于上面解释过了t.ppr()等同于Test.ppr(t),所以程序提醒我们多传了一个参数t。

这里实际上已经部分说明了self在定义时不可以省略。

当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。

class Test:
    def ppr():
        print(__class__)

Test.ppr()

运行结果:
<class &#39;__main__.Test&#39;>
Salin selepas log masuk

(3)、在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。

class Parent:
    def pprt(self):
        print(self)

class Child(Parent):
    def cprt(self):
        print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
Salin selepas log masuk

运行结果:

<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>

解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt(c),所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。

(4)、在描述符类中,self指的是描述符类的实例

class Desc:
    def __get__(self, ins, cls):
        print(&#39;self in Desc: %s &#39; % self )
        print(self, ins, cls)
class Test:
    x = Desc()
    def prt(self):
        print(&#39;self in Test: %s&#39; % self)
t = Test()
t.prt()
t.x
Salin selepas log masuk

运行结果如下:

self in Test: <__main__.Test object at 0x0000000002A570B8>
self in Desc: <__main__.Desc object at 0x000000000283E208>
<__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8>

这里主要的疑问应该在:Desc类中定义的self不是应该是调用它的实例t吗?怎么变成了Desc类的实例了呢?
因为这里调用的是t.x,也就是说是Test类的实例t的属性x,由于实例t中并没有定义属性x,所以找到了类属性x,而该属性是描述符属性,为Desc类的实例而已,所以此处并没有顶用Test的任何方法。

那么我们如果直接通过类来调用属性x也可以得到相同的结果。

下面是把t.x改为Test.x运行的结果。

self in Test: <__main__.Test object at 0x00000000022570B8>
self in Desc: <__main__.Desc object at 0x000000000223E208>
<__main__.Desc object at 0x000000000223E208> None <class &#39;__main__.Test&#39;>
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana untuk menggunakan diri dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!