今日内容

反射实战案例

案例一、

加载配置文件纯大写的配置

import settings
new_dict = {}

for i in dir(settings):
    if i.isupper():
        v = getattr(settings,i)
        new_dict[i] = v
print(new_dict)  # 打印结果{'BASE_PATH': '热爱学习', 'NAME': 'joker'}

settings内的数据

BASE_PATH = '热爱学习'
NAME = 'joker'
log = 'log.log'

案例二、

模拟操作系统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('请输入你要指令>>>:').strip()
    if hasattr(obj,cmd):
        cmd_name = getattr(obj,cmd)
        cmd_name()
    else:
        print('%s 不是内部指令或外部指令,也不是可运行的程序或批处理的文件'%cmd)

"""
请输入你要指令>>>:dir
dir获取当前目录下的所有文件名称
请输入你要指令>>>:ls
ls获取当前路劲下的所有文件名称
请输入你要指令>>>:ipconfig
ipconfig获取当前计算机的网卡信息
请输入你要指令>>>:xxx
xxx 不是内部指令或外部指令,也不是可运行的程序或批处理的文件
"""

面向对象魔法方法

魔法方法其实就是类中定义的双下方法
之所以会叫魔法方法原因是这些方法都是到达某个条件自动触发 无需调用

方法 触发条件
__init__ 实例化对象的时候自动触发
__str__ 对象被执行打印操作的时候会自动触发 该方法必须返回一个字符串 返回什么字符串打印对象就展示什么字符串
__call__ 对象加括号调用 就会自动触发该方法
__getattr__ 对象获取一个不存在的属性名 自动触发,该方法返回什么 对象获取不存在 对象获取不存在的属性名就会得到什么
__setattr__ 对象操作属性值的时候自动触发>>>:对象.属性名 = 属性值
__del__ 对象在被删除(主动 被动)的时候自动触发
__getattribute__ 对象获取属性的时候自动触发 无论这个属性存不存在 当类中既有__getattr__y又有__getattribute__的时候只会走后者
__enter__ 对象被with语法执行的时候自动触发 该方法返回什么 as关键字后面的变量名就能得到什么
__exit__ 对象被with语法执行并运行完with语法代码后 自动触发

__init__

实例化对象的时候自动触发

class MyClass(object):
    def __init__(self,):
        print('__init__方法')
m1 = MyClass()  # __init__方法

__str__

对象被执行打印操作的时候会自动触发 该方法必须返回一个字符串 返回什么字符串打印对象就展示什么字符串

class MyClass(object):
    def __init__(self):
        print('__init__方法')
    def __str__(self):
        print('__str__')
        return '我必须得是字符串'
m1 = MyClass()
print(m1)

__call__

对象加括号调用 就会自动触发该方法

class MyClass(object):
    def __call__(self, *args, **kwargs):
        print('__call__方法')
        print(args)    # ()
        print(kwargs)  # {}

m1 = MyClass()
m1()

__getattr__

对象获取一个不存在的属性名 自动触发,该方法返回什么 对象获取不存在 对象获取不存在的属性名就会得到什么

class MyClass(object):
    def __getattr__(self, item):
        print('__getattr__方法')
        print(item)
        return 'getattr'
m1 = MyClass()
print(m1.name)

__setattr__

对象操作属性值的时候自动触发>>>:对象.属性名 = 属性值

class MyClass(object):
    def __init__(self,name):
        self.name = name
    def __setattr__(self, key, value):
        print('__setattr__方法')
        print(key)    # name
        print(value)  # joker


m1 = MyClass('joker')

__del__

对象在被删除(主动 被动)的时候自动触发

class MyClass(object):
    def __del__(self):
        print('__del__方法')
m1 = MyClass()
del m1

__getattribute__

对象获取属性的时候自动触发 无论这个属性存不存在

class MyClass(object):
    def __getattribute__(self, item):
        print('__getattribute__方法')
m1 = MyClass()
m1.name

__getattr____getattribute__

对象获取属性的时候自动触发 无论这个属性存不存在 当类中既有__getattr__又有__getattribute__的时候只会走后者

class MyClass(object):
    def __getattr__(self, item):
        print('__getattr__方法')
        print(item)
        return 'getattr'
    def __getattribute__(self, item):
        print('__getattribute__方法')
m1 = MyClass()
m1.name

__enter____exit__

class MyClass(object):
    def __enter__(self):
        print('__enter__方法')
        return 'from enter'
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__方法')
m1 = MyClass()
with m1 as f:
    print(f)

魔法方法笔试题

"""补全以下代码 执行之后不报错"""
class Context:
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass
    def do_something(self):
        pass
with Context() as f:
    f.do_something()

元类简介

基础阶段我们使用type来查找数据的数据类型
但是学了面向对象之后 发现查看的不是数据类型 而是数据所属的类

s1 = '今天不在状态!!!'
l2 = [11, 22, 33, 44]
d = {'name': 'joker', 'age': 18}
print(type(s1))  # <class 'str'>
print(type(l2))  # <class 'list'>
print(type(d))  # <class 'dict'>


class MyClass:
    pass
obj = MyClass()
print(type(obj))  # 查看产生对象obj的类:<class '__main__.MyClass'>
print(type(MyClass))  # 查看产生对象MyClass的类:<class 'type'>

通过上述推导 得出结论 自定义的类都是由type类产生的
我们将产生类的类称之为 '元类'

产生类的两种方法

一、class关键字

class MyClass:
    pass

二、利用元类type

type(类名,类的父类,类的名称空间)
	type('MyClass',(),{})

学习元类其实就是掌握类的产生过程 我们就可以在类的产生过程中高度定制化类的行为

元类基本使用

class MyMetaClass(type):
    def __init__(self,what,bases=None,dict=None):
        # print('我好晕')
        if not what.istitle():
            raise Exception('首字母必须大写 你会不会写python 面向对象没学过吗')
        super().__init__(what,bases,dict)
class Myclass(metaclass=MyMetaClass):
    pass

class myclass(metaclass=MyMetaClass):  # 首字母没有大写会抛异常
    pass

元类进阶

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)  # 不使用关键字会抛出异常

obj = Myclass(name='jason',age='18')

双下new方法

"""
类产生对象的步骤
	1.产生一个空对象
	2.自动触发__init__方法实例化对象
	3.返回实例化好的对象
"""
__new__方法专门用于产生空对象				骨架
__init__方法专门用于给对象添加属性		        血肉
 posted on 2022-07-31 18:34  Joker_Ly  阅读(43)  评论(0编辑  收藏  举报