• 面向对象编程(四)


    反射案例

    1. # 2.模拟操作系统cmd终端执行用户命令
    2. class WinCmd(object):
    3. def dir(self):
    4. print('dir获取当前目录下所有的文件名称')
    5. def ls(self):
    6. print('ls获取当前路径下所有的文件名称')
    7. def ipconfig(self):
    8. print('ipconfig获取当前计算机的网卡信息')
    9. obj = WinCmd()
    10. while True:
    11. cmd = input('请输入您的命令>>>:')
    12. if hasattr(obj, cmd):
    13. cmd_name = getattr(obj, cmd)
    14. cmd_name()
    15. else:
    16. print('%s 不是内部或外部命令,也不是可运行的程序或批处理文件' % cmd)

    面向对象的魔法方法

    1.魔法方法的简介:

            在类中,有一些内置好的特定的方法,方法名是“__xxx__”,在进行特定的操作时会自动被调用,这些方法称之为魔法方法。下面介绍几种常见的魔法方法。

    2.常见的魔法方法即代码实现:

    1. '''__init__ : 实例化对象的时候自动触发,初始化一个类,在创建实例对象为其赋值'''
    2. class Person(object):
    3. def __init__(self):
    4. print('__init__方法')
    5. obj = Person()
    1. '''__call__ : 当对象加括号调用时自动触发该方法'''
    2. class Person(object):
    3. def __call__(self, *args, **kwargs):
    4. print('__call__方法')
    5. print(args)
    6. print(kwargs)
    7. obj = Person()
    8. print(obj.__call__())
    1. '''__str__ : 对象被执行打印操作的时候会自动触发,该方法必须返回一个字符串'''
    2. class Person(object):
    3. def __str__(self):
    4. return '这是类:%s 产生的一个对象'%self.name
    5. obj = Person()
    6. print(obj.__str__())
    1. '''__getattr__ : 当对象获取的属性名不存在时触发,返回获取的这个不存在的属性名'''
    2. class Person(object):
    3. def __getattr__(self, item):
    4. print('__getattr__', item)
    5. return '您想要获取的属性名:%s不存在'%item
    6. obj = Person()
    7. print(obj.__getattr__('age'))
    1. '''__setattr__ : 对象操作属性值的时候自动触发'''
    2. class Person(object):
    3. def __setattr__(self, key, value):
    4. print(key)
    5. print(value)
    6. obj = Person()
    7. print(obj.__setattr__('name','age'))
    1. '''__del__ : 对象在被主动或被动删除的时候自动触发'''
    2. class Person(object):
    3. def __init__(self,name):
    4. self.name = name
    5. def __del__(self):
    6. print('触发啦')
    7. obj = Person('把我删啦')
    8. print(obj.__del__())
    1. '''__getattribute__ :对象在获取属性的时候自动触发 不管这个属性是否存在
    2. (当一个类中既有__getattr__又有__getattribute__时只走后者)'''
    3. class Person(object):
    4. def __init__(self,name):
    5. self.name = name
    6. def __getattribute__(self, item):
    7. return super(Person, self).__getattribute__(item) # 复杂写法
    8. return super().__getattribute__(item) # 简便写法
    9. obj = Person('把我删啦')
    10. print(obj.__getattribute__('name'))
    1. '''__exit__ :对象被with语法执行并运行完with子代码之后自动触发
    2. def __exit__(self, exc_type, exc_val, exc_tb):对象被with语法执行并运行完with子代
    3. 码之后 自动触发'''
    4. class Open:
    5. def __init__(self,name):
    6. self.name=name
    7. def __enter__(self):
    8. print('对象被with语法执行的时候自动触发 该方法返回什么 as关键字后面的变量名就能得到什么')
    9. def __exit__(self, exc_type, exc_val, exc_tb):
    10. print('对象被with语法执行并运行完with子代码之后 自动触发')
    11. with Open('a.txt') as f:
    12. print(f)

    元类简介

            所有的对象都是实例化或者说是通过调用类而得到的,python中一切皆对象,通过class关键字定义的类本质也是对象,对象又是通过调用类得到的,因此通过class关键字定义的类肯定也是调用了一个类得到的,这个类就是元类

    创建类的两种方式

    1.class关键字       

    1. class Person
    2. pass

    2.利用元类type

    1. class MyMetaClass(type):
    2. pass
    3. class MyClass(metaclass = MyMetaClass)
    4. pass

    \bullet  类中的__init__用于实力化对象

    \bullet  元类中的__init__用于实例化类

    ps:只有继承了type的类才可以称之为是元类,如果想要切换产生类的元类不能使用继承需要使用关键字metaclass声明。

    1. class MyMetaClass(type):
    2. def __init__(self,what, bases=None, dict=None):
    3. # what 类名
    4. # bases 父类
    5. # dict 类的名称空间
    6. if not what.istitle():
    7. raise Exception('首字母必须大写')
    8. super().__init__(what, bases, dict)
    9. class person(metaclass=MyMetaClass):
    10. pass
    11. # 当类名不是首字母大写时报错提示首字母必须大写

    元类的升华版

    ### 元类不止能控制类的产生过程也可以控制对象的产生过程 ###

    1. class MyMetaClass(type):
    2. def __call__(self, *args, **kwargs):
    3. print('__call__')
    4. if args:
    5. raise Exception('必须用关键字参数传参')
    6. super().__call__(*args, **kwargs)
    7. class MyClass(metaclass=MyMetaClass):
    8. def __init__(self, name, age):
    9. self.name = name
    10. self.age = age
    11. print('__init__')
    12. obj = MyClass('aa', 88)
    13. # 当参数没有用关键字传参的时候会报错

    ps:如果我们想控制对象的产生过程 可以操作元类里的__call__

            如果我们想控制类里的产生过程 可以操作元类里的__init__

    元类之双下new方法

    1.new方法的作用:

            俗话讲 没对象new一个对象,所以从这句话中可以知道new方法是一个用来产生对象的方法

    2.具体用法:

    1. class Person(object):
    2. def __init(self,*args,**kwargs):
    3. print('init')
    4. def __new__(cls,*args,**kwargs):
    5. print('new')
    6. print(type(cls))
    7. obj = Person()
    8. '''打印结果
    9. new
    10. '''

    ps:创建类的一个实例时,如果该类具有__new__方法,会先调用__new__方法,__new__方法接受当前正在实例化的类作为第一个参数,这个参数的类型是type。

  • 相关阅读:
    5 年 Python ,总结的 10 条 Python 使用技巧
    C++ 的时间库:日历和时区
    java基于 ssm+jsp的线上授课作业管理系统
    centos7 升级内核
    React 入门:组件实例三大属性之refs
    35岁创业的重要性
    C++通讯录管理系统
    基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持本地图片上传与回显的功能实现(二)
    springboot二手书籍线上回收网站java ssm-0401u
    全球功率半导体市场格局:前十名供应商全是海外企业?
  • 原文地址:https://blog.csdn.net/weixin_52596593/article/details/126071279