一. 反射
1. isinstance()和issubclass()
isunstance(类名, 对象名) : 判断对象所属关系,包括父类 (注:type(对象名) is 类名 : 判断对象所属关系,只包括当前的类.)
issubclass(类名, 类名) : 判断类与类之间的继承关系
class A: pass class B(A): pass b = B() print(isinstance(b, B)) # True 判断对象b是否属于B类 print(isinstance(b, A)) # True 判断对象b是否属于A类 print(type(b) is B) # True 判断对象b是否属于B类 print(type(b) is A) # False 判断对象b是否属于A类 print(issubclass(A, B)) # False 判断A是不是B的子类 print(issubclass(B, A)) # True 判断B是不是A的子类
2. 反射
反射 : 用字符串数据类型的变量名来访问这个变量的值. python中的一切事物都是对象(都可以使用反射)
反射的方法 : getattr , hasattr, setattr, delattr
(1) getattr
getattr 接收2个参数,前面的是一个对象或者模块,后面的是一个字符串.
语法 : 命名空间.XXX == getattr(命名空间,'XXX')
#从类的角度看: class A: name = 'jack' @classmethod def func(cls): print(666) @staticmethod def func1(): print(777) # 反射查看静态属性 print(A.name) # jack print(getattr(A, 'name')) # jack # 反射调用方法 A.func() # 666 print(getattr(A, 'func')) # <bound method A.func of <class '__main__.A'>> 内存地址 getattr(A, 'func')() # 666 类方法 A.func1() # 777 print(getattr(A, 'func1')) # <function A.func1 at 0x000002436F709620> 内存地址 getattr(A, 'func1')() # 777 静态方法
# 从对象的角度来看 class A: NAME = 'STEVE' # 全局变量和类中的静态属性最好全大写 @classmethod def func(cls): print(666) @staticmethod def func1(): print(777) a = A() # 反射查看静态属性 print(getattr(a, 'NAME')) # STEVE # 反射调用方法 # 类方法 getattr(a, 'func')() # 666 # 静态方法 getattr(a, 'func1')() # 777
# 从模块的的角度 # 导入系统模块
import os # 导入os模块 os模块是别人写好的python代码的结合 os.rename('12', 'hello') # 把文件为'123'的文件名改为'hello' getattr(os, 'rename')('hello', '12') # 把文件为'hello'的文件名改为'456' ==>> os.rename # 导入自己的模块 def func1(): print(666) def func2(): print(777) import sys # 是一个模块,这个模块里的所有的方法都是和python解释器相关的 print(sys.modules) # 这个方法 表示所有在当前这个python程序中导入的模块 # 可以找到本文件的模块地址(字典类型): '__main__' from 'D:/pycharm/练习/week05/new21.py'> print(sys.modules['__main__']) # <module '__main__' from 'D:/pycharm/练习/week05/new21.py'> file = sys.modules['__main__'] file.func1() # 666 file.func2() # 777 getattr(file, 'func1')() # 666 getattr(file, 'func2')() # 777
(2) hasattr
class A: name = 'tom' def __init__(self): self.age = 18 a = A() print(hasattr(A, 'name')) # True 判断A类是否含有name属性 print(hasattr(a, 'age')) # True 判断对象a是否含有age属性 print(hasattr(a,'sex')) # False
(3) setattr , delattr
class A: def __init__(self,name): self.name = name a = A('tom') setattr(a,'name', 'jack') # 把对象a的属性name的值改成'jack' print(a.name) # jack print(a.__dict__) # {'name': 'jack'} delattr(a,'name') # 删除对象a的name属性 print(a.__dict__) # {}
二. 内置方法
格式 : __名字__ 称呼 : 类中的特殊方法\内置方法 双下方法 魔术方法 (magic_method)
类中的每一个双下方法都有它自己的特殊意义 , 所有的双下方法没有需要你在外部直接调用的, 而是总有一些其他的内置函数特殊的语法来自动触发这些双下方法
1. __call__
功能 : 对象后面加括号,触发执行。即:对象() 或者 类()()
class A: DAY = 'MONDAY' def __call__(self): print('666') a = A() a() # 666 自动执行__call__方法 A()() # 666
2. __len__
class A: def __init__(self): self.lst = [1, 2, 3, 4, 5, 6, 7] def __len__(self): print(666) return len(self.lst) a = A() # 实例化对象 print(len(a)) # 7 len()自动执行__len__方法
3. __str__
class A: def __str__(self): return '%s %s %s %s %s' %(self.name, self.age, self.sex, self.height, self.weight) def __init__(self, name, age, sex, height, weight): self.name = name self.age = age self.sex = sex self.height = height self.weight = weight a = A('jack', 18, '男', 55, 1.85) print(a) # print一个对象相当于调用一个对象的__str__方法 # jack 18 男 55 1.85 print(str(a)) # 内置的数据类型,内置的类,相当于执行__str__ # jack 18 男 55 1.85 print('1号: %s' %a) # 1号: jack 18 男 55 1.85
4. __new__
__new__ : 构造方法
在实例化之后,__init__之前先执行new来创建一块空间
class A: def __new__(cls, *args, **kwargs): obj = object.__new__(cls) # A类没有__new__,只能去找object里找 print('第一步') return obj def __init__(self): print('第二步') a = A() # 先执行__new__方法,再执行__init__方法 # 第一步 # 第二步
单例类
# 单粒类 : 只能实现一个实例化对象空间的类 class A: __INSTANCE = None def __new__(cls): if not cls.__INSTANCE : cls.__INSTANCE = object.__new__(cls) return cls.__INSTANCE def __init__(self):pass a1 = A() a2 = A() a3 = A() print(a1) # <__main__.A object at 0x000002096E378B38> print(a2) # None print(a3) # None