python:物件導向進階,python物件導向進階
1,反射反射:使用字串類型的名字去操作變數反射就沒有安全問題,去操作記憶體中已經存在的變數 #反射對象中的屬性和方法
class A: price=20print(getattr(A,'price'))
#反射對象的屬性
class A: def func(self): print('in func')a =A()a.name ='alex'ret =getattr(a,'name')#通過變數名的字串形式取到的值print(ret)#反射對象的方法
ret =getattr(a,'func')ret()
#反射類的方法:
if hasattr(A,'func')): getattr(A,'func')()
#反射類的屬性
class A: price=20print(getattr(A,'price'))
#反射模組的屬性
import myprint(getattr(my,'day'))
#反射自己模組中的變數
import sysprint(getattr(sys.modules['__main__'],'year'))getattr(sys.modules['__main__'],'qqxing')()
setattr設定/修改變數
class A: passsetattr(A,'name','alex')print(A,name)
delattr刪除變數
delattr(a,'name')
2,__str__和__repr__
改變對象的字串顯示__str__,__repr__
自定製格式化字串__format__
# 雙下方法# obj.__str__ str(obj)# obj.__repr__ repr(obj)
class Teacher: def __init__(self,name,salary): self.name =name self.salary =salary def __str__(self): return "Teacher's object :%s"%self.name def __repr__(self): return str(self.__dict__) def func(self): return 'wahaha'nezha =Teacher('nazha',250)print(nazha)print(repr(nezha))print('>>> %r'%nezha)
#object 裡有一個__str__,一旦被調用,就返回調用這個方法的#對象的記憶體位址l = [1,2,3,4,5] # 執行個體化 執行個體化了一個列表類的對象print(l)# %s str() 直接列印 實際上都是走的__str__# %r repr() 實際上都是走的__repr__# repr 是str的備胎,但str不能做repr的備胎# print(obj)/'%s'%obj/str(obj)的時候,實際上是內部調用了obj.__str__方法,如果str方法有,那麼他返回的必定是一個字串# 如果沒有__str__方法,會先找本類中的__repr__方法,再沒有再找父類中的__str__。# repr(),只會找__repr__,如果沒有找父類的
class Classes: def __init__(self,name): self.name = name self.student = [] def __len__(self): return len(self.student) def __str__(self): return 'classes'py_s9= Classes('python全棧9期')py_s9.student.append('二哥')py_s9.student.append('泰哥')print(len(py_s9))print(py_s9)
#__del__class A: def __del__(self): # 解構函式: 在刪除一個對象之前進行一些收尾工作 self.f.close()a = A()a.f = open() # 開啟檔案 第一 在作業系統中開啟了一個檔案 拿到了檔案操作符存在了記憶體中del a # a.f 拿到了檔案操作符消失在了記憶體中del a # del 既執行了這個方法,又刪除了變數
# __call__
#對象後面加括弧,觸發執行。
#註:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括弧觸發的,即:對象() 或者 類()()
class A: def __init__(self,name): self.name = name def __call__(self): ''' 列印這個對象中的所有屬性 :return: ''' for k in self.__dict__: print(k,self.__dict__[k])a = A('alex')() 3,item系列
__getitem__\__setitem__\__delitem__
class Foo: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def __getitem__(self, item): if hasattr(self,item): return self.__dict__[item] def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key]f = Foo('egon',38,'男')print(f['name'])f['hobby'] = '男'print(f.hobby,f['hobby'])del f.hobby # object 原生支援 __delattr__del f['hobby'] # 通過自己實現的print(f.__dict__)View Code4,__new__
__init__ 初始化方法
__new__ 構造方法 : 建立一個對象
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A, *args, **kwargs)a1 = A()a2 = A()a3 = A()print(a1)print(a2)print(a3)
單例模式
# 一個類 始終 只有 一個 執行個體
# 當你第一次執行個體化這個類的時候 就建立一個執行個體化的對象
# 當你之後再來執行個體化的時候 就用之前建立的對象
class A: __instance = False def __init__(self,name,age): self.name = name self.age = age def __new__(cls, *args, **kwargs): if cls.__instance: return cls.__instance cls.__instance = object.__new__(cls) return cls.__instanceegon = A('egg',38)egon.cloth = '小花襖'nezha = A('nazha',25)print(nezha)print(egon)print(nezha.name)print(egon.name)print(nezha.cloth)
5,__eq__
class A: def __init__(self,name): self.name = name def __eq__(self, other): if self.__dict__ == other.__dict__: return True else: return Falseob1 = A('egon')ob2 = A('egg')print(ob1 == ob2)
#'=='預設比較記憶體位址
6,__hash__class A:
def __init__(self,name,sex):
self.name = name
self.sex = sex
def __hash__(self):
return hash(self.name+self.sex)
a = A('egon','男')
b = A('egon','nv')
print(hash(a))
print(hash(b))
7,hashlib#提供摘要演算法
import hashlib#提供摘要演算法的模組md5 =hashlib.md5()md5.update(b'alex3714')print(md5.hexdigest())
1,不管演算法多麼不同,摘要的功能始終不變
2,對於相同的字串使用同一個演算法進行摘要,得到的值總是不變的
3,使用不同演算法對相同的字串進行摘要,得到的值應該不同
4,不管是用什麼演算法,hashlib的方式永遠不變
# 摘要演算法
# 密碼的密文儲存
# 檔案的一致性驗證
# 在下載的時候 檢查我們下載的檔案和遠程伺服器上的檔案是否一致
# 兩台機器上的兩個檔案 你想檢查這兩個檔案是否相等
#使用者的登入import hashlibusr = input('username :')pwd = input('password : ')with open('userinfo') as f: for line in f: user,passwd,role = line.split('|') md5 = hashlib.md5() md5.update(bytes(pwd,encoding='utf-8')) md5_pwd = md5.hexdigest() if usr == user and md5_pwd == passwd: print('登入成功')
#加鹽
import hashlib # 提供摘要演算法的模組md5 = hashlib.md5(bytes('鹽',encoding='utf-8'))# md5 = hashlib.md5()md5.update(b'123456')print(md5.hexdigest())加鹽
#動態加鹽
# 動態加鹽# 使用者名稱 密碼# 使用使用者名稱的一部分或者 直接使用整個使用者名稱作為鹽import hashlib # 提供摘要演算法的模組md5 = hashlib.md5(bytes('鹽',encoding='utf-8')+b'')# md5 = hashlib.md5()md5.update(b'123456')print(md5.hexdigest()) 動態加鹽
#檔案一致性的校正
import hashlibmd5 = hashlib.md5()md5.update(b'alex')md5.update(b'3714')print(md5.hexdigest())# 檔案的一致性校正這裡不需要加鹽