我的Python學習筆記(四):動態新增屬性和方法
一、動態語言相關概念
1.1 動態語言
- 在執行時程式碼可以根據某些條件改變自身結構
- 可以在執行時引進新的函式、物件、甚至程式碼,可以刪除已有的函式等其他結構上的變化
- 常見的動態語言:Object-C、C#、JavaScript、PHP、Python、Erlang
1.2 動態型別語言
- 在執行期間檢查資料型別的語言
- 資料型別不是在編譯階段決定的,而是把型別繫結延後到了執行階段
- 常見的動態型別語言:Python、Ruby、Erlang、JavaScript、swift、PHP、Perl
1.3 強型別語言
- 一旦一個變數被指定了某個資料型別,如果不經過強制型別轉換,那麼它就永遠是這個資料型別
- 常見的強型別語言:Java、C#、Python、Object-C、Ruby
Python是動態語言,動態型別語言,也是強型別語言。所以Python可以在執行時改變自身結構,動態新增/刪除屬性和方法。接下來將介紹Python如何動態新增屬性和方法。
二、動態新增屬性
2.1 新增物件屬性
class Person(object): def __init__(self, newName, newAge): self.name = newName self.age = newAge zhangsan = Person("張三", 18) zhangsan.addr= "北京" # 類物件zhangsan動態新增物件屬性addr print(zhangsan.name) # 張三 print(zhangsan.age) # 18 print(zhangsan.addr) # 北京 lisi = Person("李四", 28) print(lisi.name) # 李四 print(lisi.age) # 28 print(lisi.addr) # 'Person' object has no attribute 'addr'
由以上程式碼可知,Person類有兩個屬性:name和age。通過[物件名.屬性名
注:通過物件名新增的物件屬性,只有這個物件能使用
2.2 新增類屬性
class Person(object): def __init__(self, newName, newAge): self.name = newName self.age = newAge Person.addr = "北京" # 類Person動態新增類屬性addr zhangsan = Person("張三", 18) print(zhangsan.name) # 張三 print(zhangsan.age) # 18 print(zhangsan.addr) # 北京 lisi = Person("李四", 28) print(lisi.name) # 李四 print(lisi.age) # 28 print(lisi.addr) # 北京
由以上程式碼可知,通過[類名.屬性名]給類Person動態添加了類屬性addr,Person的類物件zhangsan和lisi都能呼叫這個屬性
注:通過類名新增的類屬性,這個類的所有物件都能使用
三、動態新增方法
類中有三種方法,例項方法,靜態方法和類方法,三種方法的區別如下:
- 例項方法:需要繫結要一個物件上,第一個引數預設使用self,會把物件作為第一個引數傳遞進來
- 靜態方法:使用裝飾器@staticmethod進行定義,類和物件都可以呼叫,不需要預設引數
- 類方法:使用裝飾器@classmethod進行定義,類和物件都可以呼叫,第一個引數預設使用cls,會把類作為第一個引數傳遞進來
3.1 新增例項方法
import types class Person(object): def __init__(self, newName, newAge): self.name = newName self.age = newAge def eat(self): print("---正在吃---") def run(self): print("---正在跑---") zhangsan = Person("張三", 18) zhangsan.eat() # ---正在吃--- zhangsan.run = types.MethodType(run, zhangsan) # 類物件zhangsan動態新增物件方法run() zhangsan.run() # ---正在跑--- lisi = Person("李四", 28) lisi.eat() # ---正在吃--- lisi.run() # 'Person' object has no attribute 'run'
由以上程式碼可知,Person類有一個方法:eat()方法。通過[types.MethodType(方法名, 物件名)]給類物件zhangsan動態添加了物件方法run(),同理,Person的另一個類物件lisi不能呼叫這個方法
注:通過物件名新增的物件方法,只有這個物件能使用
3.2 新增靜態方法
class Person(object): def __init__(self, newName, newAge): self.name = newName self.age = newAge def eat(self): print("---正在吃---") @staticmethod def staticRun(): print("---正在跑---") Person.staticRun = staticRun # 類Person動態新增靜態方法staticRun() Person.staticRun() # ---正在跑--- zhangsan = Person("張三", 18) zhangsan.eat() # ---正在吃--- zhangsan.staticRun() # ---正在跑--- lisi = Person("李四", 28) lisi.eat() # ---正在吃--- lisi.staticRun() # ---正在跑---
由以上程式碼可知,通過[類名.靜態方法名]給類Person動態添加了靜態方法staticRun(),Person類的Person的類物件zhangsan和lisi都能呼叫這個方法
注:通過類名新增的靜態方法,這個類及這個類的所有物件都能使用
3.3 新增類方法
class Person(object): def __init__(self, newName, newAge): self.name = newName self.age = newAge def eat(self): print("---正在吃---") @classmethod def classRun(cls): print("---正在跑---") Person.classRun = classRun # 類Person動態新增類方法classRun() Person.classRun() # ---正在跑--- zhangsan = Person("張三", 18) zhangsan.eat() # ---正在吃--- zhangsan.classRun() # ---正在跑--- lisi = Person("李四", 28) lisi.eat() # ---正在吃--- lisi.classRun() # ---正在跑---
由以上程式碼可知,通過[類名.類方法名]給類Person動態添加了類方法classRun(),Person類的Person的類物件zhangsan和lisi都能呼叫這個方法
注:通過類名新增的類方法,這個類及這個類的所有物件都能使用
四、__slots__的使用
通過以上內容,我們知道了如何動態的新增屬性和方法。但是,如果我們想要限制class的屬性該怎麼辦?例如:只允許Person例項新增name和age屬性。為了達到這個目的,Python允許在定義class的時候,定義一個特殊變數__slots__來限制該class能新增的屬性。
import types class Person(object): __slots__ = ("name", "age") # 定義__slots__ def __init__(self, newName, newAge): self.name = newName self.age = newAge def eat(self): print("---正在吃---") def run(self): print("---正在跑---") Person.num = 100 # 類Person動態新增類屬性num zhangsan = Person("張三", 18) print(zhangsan.name) # 張三 print(zhangsan.age) # 18 print(zhangsan.num) # 100 zhangsan.eat() # ---正在吃--- zhangsan.addr = "北京" # 'Person' object has no attribute 'addr' zhangsan.run = types.MethodType(run, zhangsan) # 'Person' object has no attribute 'run'
通過以上程式碼可知,__slots__對Person類的動態新增沒有限制,而Person類物件zhangsan不能再動態新增物件屬性和方法。
對於__slot__有以下幾個需要注意的地方:
- __slots__只對類物件進行限制,不對類進行限制
- __slots__不僅限制類物件的屬性,還限制類物件的方法
- __slots__僅對當前類起作用,對繼承的子類不起作用
- 在子類中定義__slots__,子類允許定義的屬性就是自身的__slots__加上父類的__slots__
相關推薦
我的Python學習筆記(四):動態新增屬性和方法
一、動態語言相關概念 1.1 動態語言 在執行時程式碼可以根據某些條件改變自身結構 可以在執行時引進新的函式、物件、甚至程式碼,可以刪除已有的函式等其他結構上的變化 常見的動態語言:Object-C、C#、JavaScript、PHP、Python、Erlang 1.2 動態型別語言 在執行期間檢查資料
python學習筆記(四):核心模組方法
核心模組1、__builtin__模組:一、數學運算類abs(x) 求絕對值 1、引數可以是整型,也可以是複數 2、若引數是複數,則返回複數的模 complex([real[, imag]]) 建立一個複數 divmod(a, b) 分別取商和餘數 注意:整型
【整理】python學習筆記(5)-- pygame庫的函式和方法整理
PYGAME的方法和官方文件查詢 官方文件 http://www.pygame.org/docs/ 模組 簡介 pygame.BufferProxy An array protocol view
Python3學習筆記(四):用Python實現深度優先
這裡主要是用Python實現下深度優先的概念,由於程式碼寫得比較隨意,就沒有封裝成類,而是寫成一個函式 用一個列表做為實驗資料,模擬成二叉樹結構,用遞迴的方式不斷獲取二叉樹上的左節點,一直到左節點 序號超出列表範圍,然後迴歸獲取右節點,以此來實現深度優先。 以下是程式碼
Python學習筆記(四) 列表生成式_生成器
rec triangle 小寫 ont 無限 end clas 普通 執行過程 筆記摘抄來自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431
Unity3D之Mecanim動畫系統學習筆記(四):Animation State
大致 面板 輸入 jpg any 動畫播放 速度 nsf 顯示 動畫的設置 我們先看看Animation Clip的一些設置: Loop time:動畫是否循環播放。 下面出現了3個大致一樣的選項: Root Transform Rotation:表示為播放動畫
.net core 2.0學習筆記(四):遷移.net framework 工程到.net core
編譯 its evel hashtable ref 學習筆記 inline null 創建 在遷移.net core的過程中,第一步就是要把.net framework 工程的目標框架改為.net core2.0,但是官網卻沒有提供轉換工具,需要我們自己動手完成了
java學習筆記(四):import語法
employee sign cnblogs java 調用 變量賦值 temp 職位 求職 Import 語法是給編譯器尋找特定類的適當位置的一種方法。 創建一個Employee 類,包括四個實體變量姓名(name),年齡(age),職位(designation)和薪水(s
python學習筆記(四)-數據類型
rand 兩個 urn 浪費 line 平年 randint .com .cn 0. 在 Python 中的數據類型詳解 http://www.cnblogs.com/scios/p/8026576.html 1. 為什麽布爾類型(bool)的 True 和 False 分
python學習筆記(四)字符串及字符串操作
默認 小寫字母 是不是 swap git 查找字符 英文 去掉 title 字符串 字符串可以存任意類型的字符串,比如名字,一句話等等。 字符串還有很多內置方法,對字符串進行操作,常用的方法如下: 1 name1=‘hello world‘ 2 print(nam
day3-python學習筆記(四)
end tar upper date update size upd sdi reat 字符串方法 #字符串這些方法都不會改變原來字符串的值name = ‘beSTtest‘# new_name = name.strip()#默認是去掉空格和換行符# new_name =
Boost Python學習筆記(四)
xtra public string 轉換 TP 簡單實現 amp dir rst 你將學到什麽 在Python中調用C++代碼時的傳參問題 基礎類型 Python的字符串是常量,所以C++函數參數中的std::string &必須為const 修改源文件(
python學習筆記(四)
9.png fib AS 情況 一個 命名 文檔字符串 可選 交互 break 語句和 C 中的類似,用於跳出最近的一級 for 或 while 循環。 循環可以有一個 else 子句;它在循環叠代完整個列表(對於 for )或執行條件為 false (對於 while)時
Python學習筆記(4):容器、叠代對象、叠代器、生成器、生成器表達式
iter 有一種 ref function 但是 tool 數列 edt 叠代器類型 在了解Python的數據結構時,容器(container)、可叠代對象(iterable)、叠代器(iterator)、生成器(generator)、列表/集合/字典推導式(list,se
HADOOP學習筆記(四):HBase
系統 唯一性 創建時間 必須 就是 入口 計算 hfile mapreduce HBase簡介 Hbase是分布式、面向列的開源數據庫(其實準確的說是面向列族)。HDFS為Hbase提供可靠的底層數據存儲服務,MapReduce為Hbase提供高性能的計算能力,Zooke
javaweb學習筆記(四):會話管理(1)
目錄 會話管理 1.概念 2.cookie技術 2.1 Cookie一般處理流程 2.2 Cookie類 會話管理 1.概念 一次會話: 開啟瀏覽器 -> 訪問一些伺服器內容 -> 關閉瀏覽器。(瀏覽器A給伺服器傳送請求,訪問web程式,該次會話就
學習筆記(四):使用K近鄰演算法檢測WebShell
1.資料蒐集 載入ADFA-LD中正常樣本資料: def load_adfa_training_files(rootdir): x=[] y=[] list = os.listdir(rootdir) for i in
Python 學習筆記(四)[函式進階]
異常 異常捕獲 try: myfile = open('1.txt') except Exception: print('開啟檔案錯誤') else: print('開啟檔案') myfile.close() finally: print('開啟檔案結束')
Scala學習筆記(四):apply方法說明
調用 我們 val sca 關鍵字 語法糖 方式 rgs 類型 當scala中類或者對象有一個主要用途的時候,apply方法就是一個很好地語法糖。請看下面一個簡單的例子: class Foo(foo: String) {} object Foo { def appl
python 學習筆記(九): 資料庫壓測程式設計
這個程式碼是利用多執行緒多mysql資料庫批量插入資料,可用於mysql壓測 #!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function import argp