1. 程式人生 > >Day-17 面向物件04 反射 md5加密

Day-17 面向物件04 反射 md5加密

一、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資料型別

class
Boy: 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)