一文讀懂Python中的self
神奇的self:
在Python類別中規定,函數的第一個參數是實例物件本身,並且約定俗成,把其名字寫成self。其作用相當於java中的this,表示目前類別的對象,可以呼叫目前類別中的屬性和方法。
class是物件導向的設計思想,instance(也即是 object,物件)是根據 class 創建的。
一個類別(class)應該包含資料和操作資料的方法,通俗來講就是屬性和函數(即呼叫方法)。
類別 class 中為啥用使用 self ?
在類別的程式碼(函數)中,需要存取目前的實例中的變數和函數,即存取Instance中的:
對應的變數(property):Instance. ProperyNam,去讀取之前的值和寫入新的值。
呼叫對應函數(function):Instance.function(),即執行對應的動作。
-> 而需要存取實例的變數和呼叫實例的函數,當然需要對應的實例Instance物件本身。
-> 而Python中就規定好了,函數的第一個參數,就必須是實例物件本身,並且建議,約定俗成,把其名字寫成self。
-> 所以,我們需要self(需要用到self)。
首先,在Python中類別的定義:
在python中,類別是透過關鍵字class 定義的:
class 後面緊跟著類別名,即Person,類別名稱通常大寫字母開頭,緊接著是(object),表示該類別是從哪個類別繼承下來的,通常,如果沒有合適的繼承類,就使用object 類,這是所有類別最終都會繼承的類別。
class Person(object): pass
將 Person類別實例化,建立實例化是透過 類別名稱 () 實現的。
class Person(object): pass student = Person() # 创建类的实例化 print(student) print(Person)
可以看到,變數student 指向的就是一個Person的object,後面的0x0000026EE434D8D0 是記憶體位址,每個object 的位址都不一樣,而Person 本身則是一個類別。
也可以給實例變數綁定屬性,例如:為student 綁定name 和score 屬性
class Person(object): pass student = Person() # print(student) # print(Person) student.name = "Gavin" # 为实例变量 student 绑定 name 属性 类似于 赋值 操作 student.score = 100 # 为 其绑定 score 属性 print(student.name) print(student.score)
上述的方法雖然可以為類別的實例變數綁定屬性,但是不夠方便和elegant , 由於類別可以起到模板的作用,故在創建實例的時候,可以將我們認為必須綁定屬性強制填寫進去,在python中,是透過類別中通常都會使用的一個方法,即def __init__(self) 方法,在創建實例變數的時候,就把name 和score 等屬性綁上去。
class Person(object): def __init__(self,name,score): self.name = name self.score = score student = Person('Gavin',100) # 传入 __init__ 方法中需要的参数 print(student.name) print(student.score)
傳入空參數的情況,會報錯:
class Person(object): def __init__(self,name,score): self.name = name self.score = score student = Person() # 此处应该有参数传入,却没有传 print(student.name) print(student.score)
Python影片教學》
在類別中定義多個函數相互呼叫class Person(object): def __init__(self,x,y): self.x = x self.y = y def add(self): sum = self.x + self.y return sum def square(self): squr = pow(self.x,2)+pow(self.y,2) return squr def add_square(self): c = self.add()+self.square() return c student = Person(3,4) print(student.add()) print(student.square()) print('--------- 我是可爱的分割线-----------') print(student.add_square())
除此之外,类的方法和普通函数没甚区别,当然也可以使用 默认参数、可变参数和关键字参数,例子如下:
class Person(object): def __init__(self,x,y): self.x = x self.y = y def add(self,z=16): # 设置 默认变量 z =16,这只是个普通的局部变量,非实例变量,实例变量需要 self.z = z,这样定义 sum = self.x + self.y + z return sum def square(self): squr = pow(self.x,2)+pow(self.y,2) return squr def add_square(self,z): # 调用时传入变量,这也是个普通的局部变量,非实例变量 c = self.add()+self.square() + z return c student = Person(3,4) print(student.add()) print(student.square()) print('--------- 我是可爱的分割线-----------') print(student.add_square(16))
看了上述的例子可能还是不明白 self 到底是个什么鬼,为啥要使用 self 这鬼东西?没关系,往下看:
其实 self 这家伙简单的说就是把 class 中 定义的 变量和函数 变成 实例变量和实例函数,作为类 class 的成员,使得成员间能互相调用,而不需要从外部调用 数据(变量)和 方法(函数),以实现数据的封装,以上面的 Person 类为例:
创建实例的时候需要给出实例变量 x,y, 调用函数时给出 z ,调用很容易,却不知道内部实现的细节。
总之,类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都相互独立、互不影响;方法是与实例绑定的函数,和普通的函数不同,方法可以直接访问实例的数据。
其实 self 中存储的是实例变量和实例函数的属性,可以理解为一个字典( dict ),如:{'name':'zhang','age':'18'}就是这些。
注意只有数据属性,并没有创建新的类的方法。 类----->通过实例化生成----对象---->(对象只是一串类似于字典的数据,没有把类的里的方法复制给你,python没有new这个方法!)
class Person(object): def __init__(self,x,y): self.x = x self.y = y def add(self,z=16): # 设置 z 为实例变量,即 self.z = z, z 是 class 的一个成员了,而非普通局部变量 self.z = z sum = self.x + self.y + z # z虽然已被实例化,但是依然可以当作 普通变量来用 return sum def square(self): squr = pow(self.x,2)+pow(self.y,2) return squr def add_square(self): c = self.add()+self.square() + self.z # 调用实例变量 z return c student = Person(3,4) print(student.add()) print(student.square()) print('--------- 我是可爱的分割线-----------') print(student.add_square()) print(student.z) # 函数add 中的 z 被实例化以后,就可以利用实例化的方法访问它
通过这个例子可以看出, z 本来是 add() 函数的默认形参,通过将其实例化,就可以在其他函数体内调用实例变量z
被实例化以后,就可以利用实例化的方法访问它。
那么 self 到底是什么?
class Box(object): def __init__(self, boxname, size, color): self.boxname = boxname self.size = size self.color = color # self就是用于存储对象属性的集合,就算没有属性self也是必备的 def open(self, myself): print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname)) print('-->用类自己的self,打开那个%s,%s的%s' % (self.color, self.size, self.boxname)) def close(self): print('-->关闭%s,谢谢' % self.boxname) b = Box('魔盒', '14m', '红色') b.close() b.open(b) # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。 print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。
self代表类的实例,而非类;self 就是 对象/实例 属性集合
Box 是个类-----》self 实例化------》 b对象/ 实例
class 抽象体------》实例化------》对象/实例,含有属性:{'boxname':'魔盒', ‘size’:‘14m’, 'color':'red'},即 self
self 看似是整个对象,实际上清楚地描述了类就是产生对象的过程,描述了 self 就是得到了 对象,所以 self 内的键值可以直接使用
正如自然界中一个有效的对象,必须包括:
1、描述对象的属性;2、对象的方法
所以 self是必须的,也是对象中重要的特性。
看下面的代码,感觉就更神奇了:
class Box(object): def myInit(mySelf, boxname, size, color): mySelf.boxname = boxname mySelf.size = size mySelf.color = color # 自己写一个初始化函数,一样奏效,甚至不用self命名。其它函数当中用标准self return mySelf # 返回给实例化过程一个对象!神奇!并且含有对象属性/字典 # def __init__(self, boxname, size, color): # self.boxname = boxname # self.size = size # self.color = color #注释掉原来标准的初始化 def open(self, myself): print(self) print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname)) print('-->用类自己的self,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname)) def close(self): print('-->关闭%s,谢谢' % self.boxname) # 经过改造,运行结果和标准初始化没区别 b = Box().myInit('魔盒', '14m', '红色') # b = Box('魔盒', '14m', '红色')#注释掉原来标准的初始化方法 b.close() b.open(b) # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。 print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。
换个角度来讲,对类的操作有:
1、定义属性 ; 2、调用方法
对类的反馈有:
1、得到属性 ; 2、执行方法
在 class 类的函数中,为什么 self是必要的,因为 self 是对象的载体,可以理解成一个字典,看下面代码:
class Box(object): def myInit(mySelf, boxname, size, color): print(mySelf.__dict__)#显示为{}空字典 mySelf.boxname = boxname mySelf.__dict__['aa'] = 'w'#甚至可以像字典一样操作 mySelf.size = size mySelf.color = color # 自己写一个初始化函数,一样奏效,甚至不用self命名。其它函数当中用标准self return mySelf # 返回给实例化过程一个对象!神奇!并且含有对象属性/字典 # def __init__(self, boxname, size, color): # self.boxname = boxname # self.size = size # self.color = color #注释掉原来标准的初始化 def open(self, myself): print(self) print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname)) print('-->用类自己的self,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname)) def close(self): print('-->关闭%s,谢谢' % self.boxname) # 经过改造,运行结果和标准初始化没区别 b = Box().myInit('魔盒', '14m', '红色') # b = Box('魔盒', '14m', '红色')#注释掉原来标准的初始化方法 b.close() b.open(b) # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。 print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。
注意此处的: mySelf.__dict__['aa'] = 'w' #甚至可以像字典一样操作; 在 b.__dict__ 的结果中显示为:'aa':'w'
故可以把 self 理解成存储 实例化对象属性的字典(dict), self 存储属性,而没有动作执行。
self总是指调用时的类的实例。
python 中一些特殊的实例变量:
1、私有变量(private),只有内部可以访问,外部不能访问,私有变量是在名称前以两个下划线开头,如:__name,其实私有变量也不是完全不能被外部访问,不能直接访问是因为python解释器对外把 __name 变量改成了 _类名__name,所仍然可以通过 _类名__name 来访问 __name。
2、在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
3、以一個底線開頭的實例變數名,例如_name,這樣的實例變數外部是可以存取的,但是,按照約定俗成的規定,當你看到這樣的變數時,意思就是,「雖然我可以被訪問,但是,請把我視為私有變量,不要隨意訪問」。
以上是一文讀懂Python中的self的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

在CentOS系統上高效訓練PyTorch模型,需要分步驟進行,本文將提供詳細指南。一、環境準備:Python及依賴項安裝:CentOS系統通常預裝Python,但版本可能較舊。建議使用yum或dnf安裝Python3併升級pip:sudoyumupdatepython3(或sudodnfupdatepython3),pip3install--upgradepip。 CUDA與cuDNN(GPU加速):如果使用NVIDIAGPU,需安裝CUDATool

Docker利用Linux內核特性,提供高效、隔離的應用運行環境。其工作原理如下:1. 鏡像作為只讀模板,包含運行應用所需的一切;2. 聯合文件系統(UnionFS)層疊多個文件系統,只存儲差異部分,節省空間並加快速度;3. 守護進程管理鏡像和容器,客戶端用於交互;4. Namespaces和cgroups實現容器隔離和資源限制;5. 多種網絡模式支持容器互聯。理解這些核心概念,才能更好地利用Docker。

在CentOS系統上啟用PyTorchGPU加速,需要安裝CUDA、cuDNN以及PyTorch的GPU版本。以下步驟將引導您完成這一過程:CUDA和cuDNN安裝確定CUDA版本兼容性:使用nvidia-smi命令查看您的NVIDIA顯卡支持的CUDA版本。例如,您的MX450顯卡可能支持CUDA11.1或更高版本。下載並安裝CUDAToolkit:訪問NVIDIACUDAToolkit官網,根據您顯卡支持的最高CUDA版本下載並安裝相應的版本。安裝cuDNN庫:前

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

MinIO對象存儲:CentOS系統下的高性能部署MinIO是一款基於Go語言開發的高性能、分佈式對象存儲系統,與AmazonS3兼容。它支持多種客戶端語言,包括Java、Python、JavaScript和Go。本文將簡要介紹MinIO在CentOS系統上的安裝和兼容性。 CentOS版本兼容性MinIO已在多個CentOS版本上得到驗證,包括但不限於:CentOS7.9:提供完整的安裝指南,涵蓋集群配置、環境準備、配置文件設置、磁盤分區以及MinI

在CentOS下選擇PyTorch版本時,需要考慮以下幾個關鍵因素:1.CUDA版本兼容性GPU支持:如果你有NVIDIAGPU並且希望利用GPU加速,需要選擇支持相應CUDA版本的PyTorch。可以通過運行nvidia-smi命令查看你的顯卡支持的CUDA版本。 CPU版本:如果沒有GPU或不想使用GPU,可以選擇CPU版本的PyTorch。 2.Python版本PyTorch

CentOS 安裝 Nginx 需要遵循以下步驟:安裝依賴包,如開發工具、pcre-devel 和 openssl-devel。下載 Nginx 源碼包,解壓後編譯安裝,並指定安裝路徑為 /usr/local/nginx。創建 Nginx 用戶和用戶組,並設置權限。修改配置文件 nginx.conf,配置監聽端口和域名/IP 地址。啟動 Nginx 服務。需要注意常見的錯誤,如依賴問題、端口衝突和配置文件錯誤。性能優化需要根據具體情況調整,如開啟緩存和調整 worker 進程數量。
