反射实战案例
1.加载配置文件纯大写的配置
import settings
new_dict = {}
for i in dir(settings):
if i.isupper():
v = getattr(settings, i)
new_dict[i] = v
print(new_dict)
2.模拟操作系统cmd终端执行用户命令
class WinCmd(object):
def dir(self):
print('dir获取当前目录下所有的文件名称')
def ls(self):
print('ls获取当前路径下所有的文件名称')
def ipconfig(self):
print('ipconfig获取当前计算机的网卡信息')
obj = WinCmd()
while True:
cmd = input('请输入您的命令>>>:')
if hasattr(obj, cmd):
cmd_name = getattr(obj, cmd)
cmd_name()
else:
print('%s 不是内部或外部命令,也不是可运行的程序或批处理文件' % cmd)
面向对象双下方法
魔法方法其实就是类中定义的双下方法,之所以会叫魔法方法原因是这些方法都是到达某个条件自动触发 无需调用。
eg: __init__方法在给对象设置独有数据的时候自动触发(实例化)
class MyClass(object):
def __init__(self, name):
print('__init__方法')
self.name = name
def __str__(self):
print('__str__方法')
return 'aaa'
def __call__(self, *args, **kwargs):
print('__call__方法')
def __del__(self):
print('__del__方法')
def __getattr__(self, item):
print('__getattr__', item)
def __setattr__(self, key, value):
print('__setattr__')
print(key, value)
if key == 'gender':
raise Exception('你不能拥有gender属性')
super().__setattr__(key, value)
def __getattribute__(self, item):
print('__getattribute__ 方法')
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
pass
元类
"""
基础阶段我们使用type来查找数据的数据类型
但是学了面向对象之后 发现查看的不是数据类型 而是数据所属的类
我们定义的数据类型 其实本质还是通过各个类产生了对象
class str:
pass
h = 'hello' str('hello')
我们也可以理解为type用于查看产生当前对象的类是谁
"""
class MyClass:
pass
obj = MyClass()
print(type(obj))
print(type(MyClass))
"""
通过上述推导 得出结论 自定义的类都是由type类产生的
我们将产生类的类称之为 '元类'
"""
产生类的两种方式
方式1:class 类名:
class C1():
pass
print(C1)
方式2:type(类名, 父类, 类的名称空间)
C1 = type('C1', (), {})
print(C1)
元类的基本使用
学习元类的目的:'元类能够控制类的创建,学习元类我们就可以高度定制类的行为'
需求:要求类的首字母必须大写
思考:在哪里编写定制化代码 由已知推未知
对象的产生过程>>> 类里边的__init__方法
类的产生过程??? >>> 元类里的__init__方法>>>修改元类
注意:修改元类的时候不能直接继承我们自己构造的‘元类’,必须指定关键字参数'metaclass=类名'
class MyTypeClass(type):
def __init__(cls, cls_name, cls_bases, cls_dict):
print(cls, cls_name, cls_bases, cls_dict)
if not cls_name.istitle():
raise Exception('类名首字母必须大写')
super().__init__(cls_name, cls_bases, cls_dict)
class C1(metaclass=MyTypeClass):
pass
元类进阶操作
1.回想__call__方法
对象加括号会自动执行产生对象的类里边的__call__方法,并且该方法返回什么,对象加括号就得到什么
推导:类也可以看做是一个对象,那么类加括号会自动执行元类(产生类的类)里边的__call__方法,同样,该方法返回什么,类加括号就得到什么
class MyMetaClass(type):
def __call__(self, *args, **kwargs):
print('__call__')
if args:
raise Exception('必须用关键字参数传参')
super().__call__(*args, **kwargs)
class MyClass(metaclass=MyMetaClass):
def __init__(self, name, age):
self.name = name
self.age = age
print('__init__')
obj = MyClass('jason', 18)
总结
"""
如果我们想高度定制对象的产生过程,可以操作元类里面的__call__
如果我们想高度定制类的产生过程,可以操作元类里面的__init__
"""
双下new方法
"""
类产生对象的步骤
1.产生一个空对象
2.自动触发__init__方法实例化对象
3.返回实例化好的对象
"""
__new__方法专门用于产生空对象 骨架
__init__方法专门用于给对象添加属性 血肉