Day-17 面向物件04 反射 md5加密
阿新 • • 發佈:2018-11-09
一、isinstance,type,issubclass
isinstance()這個內建函式可以幫我們判斷xxx類是否是yyy型別的子類。
class Base: pass class Foo(Base): pass class Bar(Foo): pass print(issubclass(Bar, Foo)) #True print(issubclass(Foo, Bar)) #False print(issubclass(Bar, Base)) #True
type可以幫我們判斷xxx是否是xxx資料型別
classBoy: pass class Girl: pass # 統計傳進來的男生和女生分別有多少 def func(*args): b = 0 g = 0 for obj in args: if type(obj) == Boy: b += 1 elif type(obj) == Girl: g += 1 return b, g ret = func(Boy(), Girl(), Girl(), Girl(), Boy(), Boy(), Girl()) print(ret)
isinstance也可以判斷xxx是yyy型別的資料,但是isinstance沒有type那麼準確
class Base: pass class Foo(Base): pass class Bar(Foo): pass print(isinstance(Foo(), Foo)) # True print(isinstance(Foo(), Base)) # True print(isinstance(Foo(), Bar)) # False
isinstance可以判斷該物件是否是xxx家族體系中的(只能往上判斷)
二、區分函式和方法
class Foo: def chi(self): print("我是吃") @staticmethod def static_method(): pass @classmethod def class_method(cls): pass f = Foo() print(f.chi) # <bound method Foo.chi of <__main__.Foo object at 0x10f688550>> print(Foo.chi) # <function Foo.chi at 0x10e24a488> print(Foo.static_method) # <function Foo.static_method at 0x10b5fe620> print(Foo.class_method) # bound method Foo.class_method of <class '__main__.Foo'>> print(f.static_method) # <function Foo.static_method at 0x10e1c0620> print(f.class_method) #<bound method Foo.class_method of <class '__main__.Foo'>>
我們能得出以下結論:
1.類方法,不論任何情況都是方法
2.靜態方法,不論任何情況都是函式
3.例項方法,如果是例項訪問就是方法,如果是類名訪問就是函式
我們可以藉助types模組來幫我們分辨程式到底是方法還是函式:
# 所有的方法都是MethodType的例項 # 所有的函式都是FunctionType的例項 from types import MethodType, FunctionType def func(): pass print(isinstance(func, FunctionType)) # True print(isinstance(func, MethodType)) # False class Foo: def chi(self): print("我是吃") @staticmethod def static_method(): pass @classmethod def class_method(cls): pass obj = Foo() print(type(obj.chi)) # method print(type(Foo.chi)) # function print(isinstance(obj.chi, MethodType)) # True print(isinstance(Foo.chi, FunctionType)) # True print(isinstance(Foo.static_method, FunctionType)) # True print(isinstance(Foo.static_method, MethodType)) # False print(isinstance(Foo.class_method, FunctionType)) # False print(isinstance(Foo.class_method, MethodType)) # True
三、反射
關於反射, 其實一共有4個函式:
1. hasattr(obj, str) 判斷obj中是否包含str成員
2. getattr(obj,str) 從obj中獲取str成員
3. setattr(obj, str, value) 把obj中的str成員設定成value. 注意. 這裡的value可以是值, 也可以是函式
或者方法
4. delattr(obj, str) 把obj中的str成員刪除掉
注意, 以上操作都是在記憶體中進行的. 並不會影響你的原始碼
class Foo: pass f = Foo() print(hasattr(f, "chi")) # False setattr(f, "chi", "123") print(f.chi) # 被添加了一個屬性資訊 setattr(f, "chi", lambda x: x + 1) print(f.chi(3)) # 4 print(f.chi) # 此時的chi既不是靜態方法, 也不是例項方法, 更不是類方法. 就相當於你在類中寫了個self.chi = lambda 是一樣的 print(f.__dict__) # {'chi': <function <lambda> at 0x107f28e18>} delattr(f, "chi") print(hasattr(f, "chi")) # False
四、md5加密
md5是一種不可逆的加密演算法,它是可靠的,並且安全的
import hashlib
obj = hashlib.md5(加鹽)
obj.update(銘文的bytes)
obj.hexdigest() 獲取密文
import hashlib def my_md5(s): obj = hashlib.md5(b"fjlksajflkjasfsalwer123dfskjf") obj.update(s.encode("utf-8")) # 加密的必須是位元組 miwen = obj.hexdigest() return miwen # alex: 99fca4b872fa901aac30c3e952ca786d username = input("請輸入使用者名稱:") password = input("請輸入密碼:") # 資料儲存的時候. # username: my_md5(password)