一、issubclass,type,isinstance
issubclasss()这个内置函数可以帮我们判断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)