面向對象初級
面向對象初級:
????1.面向對象三大特征:封裝??繼承 ??多態????self含義:??指向實例對象本身,讓實例能夠訪問類中的屬性和方法
????2.類和對象的創建:????
類和對象的創建(登錄注冊功能)
class User:
def __init__(self,name,pwd):
self.name = name
self.pwd = pwd
class User_Mannager():
def __init__(self):
self.user_list = []#存放User類對象
def regist(self):
"""
用戶注冊
"""
while True:
name = input('輸入用戶名N(退出):')
if name.upper() == 'N':
break
for item in self.user_list:
if item.name == name:
print('用戶名已存在,重新輸入')
flag = True
break
else:
pwd = input('輸入密碼:')
self.user_list.append(User(name,pwd))
print('注冊成功')
return
continue
def Login(self):
"""
用戶登錄
"""
while True:
name = input('輸入用戶名:')
pwd = input('輸入密碼:')
for i in self.user_list:
if i.name == name and i.pwd == pwd:
print('登錄成功')
return
else:
print('用戶名密碼錯誤')
continue
def run(self):
"""
程序入口
"""
while True:
func_dict = {'1':self.Login,'2':self.regist}
print('界面(N退出):1【登錄】2.【注冊】')
num = input('輸入:')
if num.upper() == 'N':
return
func = func_dict.get(num)
if func:
func()
else:
print('輸入錯誤')
if __name__ == "__main__":
obj = User_Mannager()
obj.run()
屬性:對象具有的特征叫屬性
????設置和獲取對象具有的屬性:
??????1,靜態??類中: 對象.屬性=值????
??????????? 外部: 設置:obj = Foo(屬性的值)
?????????????? 獲取:對象.屬性??
??????2,動態(反射):以字符串的形式去設置獲取對象屬性??類中:對象.屬性=值或者pass??
????????????????????????????????外部:setattr:新增此對象的屬性及值或者修改此對象已經具有的屬性的值 ??
???????????????????????????????????格式:setattr(對象 ,屬性 (字符串形式),值 (任意類型))
???????????????????????????????????getattr:獲取對象已經具有的屬性(函數、類、變量)???????????????
???????????????????????????????????格式:getattr(對象,屬性 ?(字符串形式),默認值(屬性不存在時返回,任意類型)
???????????????????????????????????delattr:刪除對象屬性
???????????????????????????????????格式:delattr(對象,屬性)
???????????????????????????????????hasattr:檢查對象是否有某個屬性,返回布爾類型
???????????????????????????????????格式:hasattr(對象,屬性(字符串形式))
屬性的設置和獲取(靜態和動態)
#設置和獲取對象的值方法一(靜態):
class Foo:
def __init__(self,n,p): #給這個類所創建的對象中公有的屬性進行值的初始化
self.name = n
self.pwd = p
obj = Foo('guohan',123) #設置對象屬性的值(對象屬性的值封裝到對象中)
print(obj.name) #獲取對象的值
#>>>guohan
#設置和獲取對象的值方法二(動態:內置函數): setattr getattr
class Person:
# 類屬性(也可以通過字符串操作)
species = "human"
def __init__(self, name, age):
# 實例屬性
self.name = name
self.age = age
# 創建實例
p = Person("Alice", 30)
# 1. 檢查屬性是否存在(hasattr)
print(hasattr(p, "name")) # True(存在實例屬性name)
print(hasattr(p, "gender")) # False(不存在gender屬性)
print(hasattr(Person, "species")) # True(存在類屬性species)
# 2. 獲取屬性值(getattr)
# 獲取實例屬性
print(getattr(p, "name")) # Alice(等價于 p.name)
# 獲取類屬性
print(getattr(Person, "species")) # human(等價于 Person.species)
# 獲取不存在的屬性,指定默認值
print(getattr(p, "gender", "unknown")) # unknown(避免報錯)
# 3. 設置屬性值(setattr)
# 修改已有實例屬性
setattr(p, "age", 31)
print(p.age) # 31(等價于 p.age = 31)
# 新增實例屬性
setattr(p, "gender", "female")
print(p.gender) # female(動態新增屬性)
# 修改類屬性
setattr(Person, "species", "Homo sapiens")
print(Person.species) # Homo sapiens(等價于 Person.species = ...)
# 4. 刪除屬性(delattr)
# 刪除實例屬性
delattr(p, "gender")
# print(p.gender) # 報錯:AttributeError(已刪除)
# 刪除類屬性
delattr(Person, "species")
# print(Person.species) # 報錯:AttributeError(已刪除)
????
??impor_module和反射結合:19-13 反射:import_module與反射的結合_嗶哩嗶哩_bilibili
import_module(Python importlib 模塊的函數)與反射結合,核心作用是在運行時動態加載模塊,并通過字符串形式操作該模塊內的屬性(如函數、類、變量),無需在代碼中硬編碼導入路徑和屬性名。
核心原理與步驟

??????3.封裝:????同一類的方法封裝到同一類中????值封裝到對象中
????????????類中的屬性和方法:公有(一般都是)??私有(以_開頭):類實例化的對象無法直接訪問私有成員(屬性和方法)
????????????獲取對象中封裝的所有值
對象.__dict__以字典形式獲取對象的屬性和值
#獲取對象中封裝的所有的屬性
class Foo:
def __init__(self,name,pwd,eamil):
self.name = name
self.pwd = pwd
self.eamil = eamil
obj = Foo('guohan','123','888')
print(obj.__dict__)
#>>>{'name': 'guohan', 'pwd': '123', 'eamil': '888'}
setattr(obj,'name','gh')
print(obj.__dict__)
#>>>{'name': 'gh', 'pwd': '123', 'eamil': '888'}
#獲取對象中封裝的所有的屬性(私有屬性也可以看,因為私有屬性本質上還是實例對象的屬性 只是普通的對象.屬性無法直接看到 而__dict__可以獲取你所有屬性不管你私有還是公有)
class Foo:
def __init__(self,name,pwd):
self.name = name #設置私有屬性,對象不能直接訪問
self.__pwd = pwd
@property
def func(self):
return self.__pwd
@func.setter
def func(self,value):
self.__pwd = value
@func.deleter
def func(self):
del self.__pwd
obj = Foo('guohan','123')
obj.func = 888
print(obj.__dict__)
>>>{'name': 'guohan', '_Foo__pwd': 888}
????4.繼承:????搞清楚self是誰由誰創建 調用方法時去self自己的類中去找??
????????????查找方法順序:先再自己類中找再去基類找(多個基類則由左至右)??時刻注意self是誰
????5.多態:????對于一個函數而言,Python對于參數的類型不會限制,那么傳入參數時就可以是各種類型,在函數中如果有例如:arg.方法,那么就是對于傳入類型的一個限制(類型必須有該方法)。
??????????? 這就是鴨子模型只要有該方法,就是我們要想的類型
????6.私有屬性和私有方法:
????????????私有屬性self__屬性名 = 值??私有屬性不允許類的對象直接訪問,只能通過類內部的公有方法間接操作??比如類中公有方法可以訪問私有屬性故用property修飾方法將其偽裝成屬性再去間接訪問私有屬性
# 強制訪問私有成員
class Foo:
def __init__(self,name):
self.__x = name
obj = Foo('alex')
print(obj._Foo__x) # 強制訪問私有實例變量
????????????私有方法def__方法名():??私有方法不能被類的對象直接調用,只能在類內部使用。
應用
分頁查看(面向對象版)
#分頁顯示(面向對象版)
#顯示頁面內容等方法:面向對象編程
#用戶輸入:函數式編程
class Page:
page_count = 10
def __init__(self,path,page):
self.path = path
self.page = int(page)
def content(self):
page_content = []
data = 0
stat = Page.page_count*(self.page-1)
end = Page.page_count*self.page
with open(self.path,'r',encoding='utf-8') as obj:
for item in obj:
new_item = item.strip('\n')
if data>=end:
break
elif data>=stat:
page_content.append(new_item)
data+=1
for item in page_content:
print(item)
while True:
page = input('輸入查看的頁碼(N退出):')
path = input('輸入查看的文件名:')
if page.upper() == 'N':
break
obj = Page(path,page)
obj.content()
????7.棧:后進先出
class Foo(object):
"""
后進先出(理解:地鐵站,后進車廂的離門近,先出去)
"""
def __init__(self):
self.data_list = []
def push(self, val):
"""
向棧中壓入一個數據(入棧)
:param val:
:return:
"""
self.data_list.append(val)
def pop(self):
"""
從棧中拿走一個數據(出棧)
:return:
"""
return self.data_list.pop()
obj = Foo()
obj.push(6)
obj.push(7)
obj.push(8)
print(obj.pop())
#>>>8
浙公網安備 33010602011771號