Day29

总结

反射

# 面向对象终端功能
    class WinCmd(object):
        def ls(self):
            print('windows系统正在执行ls命令')
        def dir(self):
            print('windows系统正在执行dir命令')
        def cd(self):
            print('windows系统正在执行cd命令')

    class LinuxCmd(object):
        def ls(self):
            print('Linux系统正在执行ls命令')
        def dir(self):
            print('Linux系统正在执行dir命令')
        def cd(self):
            print('Linux系统正在执行cd命令')

    obj = WinCmd()
    obj1 = LinuxCmd()
# 利用反射操作数据和功能
    def run(obj):
        while True:
            cmd = input('请输入您的指令>>>:')
            if hasattr(obj, cmd):
                func_name = getattr(obj, cmd)
                func_name()
            else:
                print('cmd command not found')   
    run(obj1)
    run(obj)

面向对象的双下方法

'''
	又名魔法方法,有些双下方法不需要调用,到达特定条件会自动触发
'''
1.__str__
	对象被执行打印时自动触发
     该方法必须返回字符串类型的数据,很多时候用来更加精准的描述对象

2.__del__
	对象被执行(被动、主动)删除操作之后自动执行

3.__getattr__
	对象查找不存在名字的时候自动触发

4.__setattr__
	对象在执行添加属性操作的时候自动触发	>>>	obj.变量名=变量值
 
5.__call__
	对象被加括号调用的时候自动触发

6.__enter__
	对象被执行with上下文管理语法开始自动触发 
  	该方法返回什么as后面的变量名就会得到什么
  
7.__exit__
	对象被执行with上下文管理语法结束之后自动触发

8.__getattribute__
	只要对象查找名字无论名字是否存在都会执行该方法
  	如果类中有__getattribute__方法 那么就不会去执行__getattr__方法

9.__new__
	__new__用于产生空对象(类)		骨架
	__init__用于实例化对象(类)		血肉
"""
	不是所有的地方都可以直接调用__new__ 
	如果是在元类的__new__里面 可以直接调用
    class Meta(type):
        def __new__(cls, *args, **kwargs):
            obj = type.__new__(cls, *args, **kwargs)
            return obj
	如果是在元类的__call__里面 则需要间接调用
    class Mate(type):
        def __call__(self, *args, **kwargs):
            obj = object.__new__(self)  # 创建一个空对象
            self.__init__(obj, *args, **kwargs)  # 让对象去初始化
            return obj	
"""

元类

# 元类是产生类的类

print(type(123))  # <class 'int'>
print(type([1, 2, 3]))  # <class 'list'>
print(type({'name':'jason','pwd':123}))  # <class 'dict'>
# type查询其实是对象所属的类名称
# type是所有类的元类
class MyClass(object):
    pass
obj = MyClass()
print(type(obj))
print(type(MyClass))  # <class 'type'>

产生类的两种表现形式

# class关键字
    class MyClass(object):
        pass
    print(MyClass)  # <class '__main__.MyClass'>
# type元类
    # type(类名,父类,类的名称空间)
    res = type('MyClass', (), {})
    print(res)  # <class '__main__.MyClass'>

# 元类能够控制类的创建,我们可以利用这一点定制类的行为

元类操作

# 类里的__init__方法和元类里面的__call__方法执行的先后顺序
    class MyTypeClass(type):
        def __call__(self, *args, **kwargs):
            print('__call__ run')
            super().__call__(*args, **kwargs)


    class MyClass(metaclass=MyTypeClass):
        def __init__(self, name):
            print('__init__ run')
            self.name = name


    obj = MyClass('jason')
    '''
        __call__ run
        __init__ run	
    '''
# 定制对象的产生过程
    class MyTypeClass(type):
        def __call__(self, *args, **kwargs):
            # print('__call__ run')
            # print(args,kwargs)
            if args:
                raise Exception('必须全部采用关键字参数')
            super().__call__(*args, **kwargs)


    class MyClass(metaclass=MyTypeClass):
        def __init__(self, name):
            # print('__init__ run')
            self.name = name
    obj1 = MyClass('jason')  # 报错 Exception: 必须全部采用关键字参数
    obj2 = MyClass(name='jason')	
posted @ 2022-04-11 22:08  有梦想的阿九  阅读(36)  评论(0)    收藏  举报