91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python面向對象編程的反射怎么使用

發布時間:2021-11-25 09:20:26 來源:億速云 閱讀:158 作者:iii 欄目:互聯網科技

這篇文章主要介紹“python面向對象編程的反射怎么使用”,在日常操作中,相信很多人在python面向對象編程的反射怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”python面向對象編程的反射怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

關于命名空間

昨天講反射的內容主要是getattr、hasattr、setattr、delattr、callable這五個函數。其中有一個關鍵詞——命名空間,這是個非常非常重要的概念,深入學python一定要對命名空間有非常清楚的理解和認識。

命名空間是python程序在運行時向操作系統申請的一塊有名字的內存空間。我們把內存想象成一幢大樓,那么python解釋器執行腳本(當前執行的py文件)時會申請一層樓存放當前執行的py文件中的數據和代碼塊,這塊命名空間的名字叫__main__;若在這個文件中定義了類,那么會在樓層里給這個類單獨開辟一個房間用來存放這個類內部的數據和代碼塊,房間的名字就是類名;創建類的實例時也會給實例單獨開辟一個房間,里面存放了實例的屬性和類指針,訪問實例的屬性時在實例的命名空間中找,訪問實例的綁定方法時通過類指針到類的房間里找,房間的名字就是實例的名字。假設我們導入了其他的模塊,那么python解釋器會向系統新申請一層樓來存放被導入的py文件,同理可以推導出新導入的py文件中也可能定義了類和創建了類的實例。那些類和它的實例都會存放在新的樓層,這個新的樓層名字就是py文件名。

以下通過案例和圖例進行詳細講解:

有一個animal_file.py文件,內容如下:

class Animal:kind = '動物'def __init__(self, name):self.name = namedef eat(self):print(f'{self.name}正在進食!')

另有一個run.py文件,內容如下:

import animal_fileclass Cat(animal_file.Animal):def __init__(self, name, count=0):self.count = count
        animal_file.Animal.__init__(self, name)def mousing(self):print(f'貓咪“{self.name}”捉住了{self.count}只老鼠')white_cat = Cat('大白貓')white_cat.mousing()out:貓咪“大白貓”捉住了0只老鼠

實例圖如下:

python面向對象編程的反射怎么使用

執行run.py文件時會先申請一塊名字叫__main__的命名空間;執行import animal_file語句時會新申請一塊名字叫animal_file的命名空間,導入文件內容時會在animal_file的命名空間內開辟一塊名字叫Animal類的名稱空間,內部有kind變量和__init__方法以及eat方法,導入完畢后返回run.py文件繼續執行;執行class Cat(animal_file.Animal):語句時會__main__的命名空間內開辟一塊名字叫Cat的名稱空間,內部有指向Animal類的父類指針、__init__方法和mousing方法;創建white_cat實例時會__main__的命名空間內開辟一塊名字叫white_cat的名稱空間,內部有指向本類的指針、name屬性和count屬性。

以上就是關于命名空間的內容和代碼實例、圖例詳細講解,對命名空間概念還不清楚的朋友一定不要嫌啰嗦,耐心看完并理解,最好自己嘗試畫圖,一定要把命名空間概念搞得清清楚楚。

反射的實例1——登錄驗證

代碼如下:

class Authentic:lst = [('登錄', 'login'), ('注冊', 'register'), ('列表', 'table')]def __init__(self, name, pwd):self.name = name
        self.pwd = pwd
        self.table = '測試列表'def register(self):name = input('請輸入用戶名:')pwd1 = input('請輸入密碼:')pwd2 = input('請再輸入一次:')if pwd1 == pwd2 and len(pwd1) > 5:self.name = name
            self.pwd = pwd1print(f'注冊賬號"{name}"成功')else:print('兩次密碼不一致或密碼長度小于6,注冊失敗')def login(self):name = input('請輸入用戶名:')pwd = input('請輸入密碼:')if pwd == self.pwd and name == self.name:print(f'登錄賬號"{name}"成功')else:print('用戶名或密碼不對,登錄失敗!')user = Authentic('abc', '123456')while 1:for j, i in enumerate(Authentic.lst):print(f'{j+1}.{i[0]}', '\t', end='')print()ret = input('請輸入你的選擇:')if ret.upper() == 'Q':breakelse:try:choice = Authentic.lst[int(ret)-1][1]if hasattr(user, choice):if callable(ret := getattr(user, choice)):ret()else:print(ret)except (IndexError, ValueError):pass

以上是一個登錄驗證功能的極簡示例,在Authentic類中定義了login、register兩個方法,對應的菜單選項有3條;接下來初始化實例user,然后進入循環,循環體內開始先打印選項列表,再接受用戶輸入;判斷輸入內容是’q’或’Q’則退出循環;否則則嘗試對輸入內容轉成數字并用它對列表取值(嘗試的時候發生索引越界或不是數字類型的錯誤均忽略),取值成功后choice的內容是字符串’login’或’register’或’table’之中的一種,然后對choice值判斷,可執行的則執行它,不可執行的則打印它。

以上是使用反射的一個簡單案例。粗看平平無奇,請對比一下不使用反射實現同樣功能的代碼:

user = Authentic('abc', '123456')while 1:for j, i in enumerate(Authentic.lst):print(f'{j+1}.{i[0]}', '\t', end='')print()ret = input('請輸入你的選擇:')if ret.upper() == 'Q':breakelif ret == '1':user.login()elif ret == '2':user.register()elif ret == '3':print(user.table)

請仔細思考一下,目前選項列表是3項,使用了3次elif,如果選項多達幾十項,那么代碼是不是要隨著選項列表的增加而新增幾十項elif?回頭再看使用反射實現的代碼,無論選項列表是3項、30項、甚至300項都不需要增加elif判斷。

反射的實例2——文件操作

3行代碼實現文件操作的腳本,現在嘗試新建一個py文件,內容如下,文件名叫f.py

import shutilfrom sys import argvgetattr(shutil, argv[1].lower())(argv[2], argv[3])

再打開cmd窗口,進入f.py文件所在的目錄。

執行下面的命令:

python f.py copy f.py fpy.bak
python f.py move fpy.bak f1.py
python f.py rename f1.py f2.py

每次執行完可以檢查一下命令是否正常執行。

如何獲取當前腳本的名字內容

關于反射,大家都知道了用getattr可獲得指定命名空間中指定名字的內容,但是如何獲取當前腳本的名字內容呢?首先import sys,然后使用sys.modules[’__main__’]可獲得當前腳本的命名空間。

假設有一個小需求,a變量值為123,b變量值為’abc’,判斷用戶輸入a,則打印123,判斷輸入是b則打印’abc’。

import sys

a = 123b = 'abc'ret = input('請輸入要打印的名字:')if hasattr(sys.modules['__main__'], ret):print(getattr(sys.modules['__main__'], ret))

想象一下如果變量名字有幾十個,用通常的if elif else的寫法是不是需要寫幾十行?用反射簡單的2行代碼即搞定一大堆if eilf else。

到此,關于“python面向對象編程的反射怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沙湾县| 武宣县| 昭觉县| 尼勒克县| 襄城县| 改则县| 安福县| 南宫市| 卢氏县| 中宁县| 桂林市| 沙雅县| 临城县| 广昌县| 凌云县| 剑川县| 崇明县| 西贡区| 湘乡市| 台南市| 宁国市| 安义县| 阜宁县| 辽阳市| 防城港市| 裕民县| 潞西市| 新密市| 开鲁县| 阿巴嘎旗| 朔州市| 宜良县| 社旗县| 屏边| 高唐县| 廊坊市| 和政县| 东平县| 改则县| 甘德县| 夏河县|