面向对象编程(四)

反射案例

# 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)

面向对象的魔法方法

1.魔法方法的简介:

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

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

'''__init__ : 实例化对象的时候自动触发,初始化一个类,在创建实例对象为其赋值'''
class Person(object):
    def __init__(self):
        print('__init__方法')
obj = Person()
'''__call__ : 当对象加括号调用时自动触发该方法'''
class Person(object):
    def __call__(self, *args, **kwargs):
        print('__call__方法')
        print(args)
        print(kwargs)
obj = Person()
print(obj.__call__())
'''__str__ : 对象被执行打印操作的时候会自动触发,该方法必须返回一个字符串'''
class Person(object):
    def __str__(self):
        return '这是类:%s 产生的一个对象'%self.name
obj = Person()
print(obj.__str__())
'''__getattr__ : 当对象获取的属性名不存在时触发,返回获取的这个不存在的属性名'''
class Person(object):
    def __getattr__(self, item):
        print('__getattr__', item)
        return '您想要获取的属性名:%s不存在'%item
obj  = Person()
print(obj.__getattr__('age'))
'''__setattr__ : 对象操作属性值的时候自动触发'''
class Person(object):
    def __setattr__(self, key, value):
        print(key)
        print(value)
obj  = Person()
print(obj.__setattr__('name','age'))
'''__del__ : 对象在被主动或被动删除的时候自动触发'''
class Person(object):
    def __init__(self,name):
        self.name = name
    def __del__(self):
        print('触发啦')

obj  = Person('把我删啦')
print(obj.__del__())
'''__getattribute__ :对象在获取属性的时候自动触发 不管这个属性是否存在
(当一个类中既有__getattr__又有__getattribute__时只走后者)'''
class Person(object):
    def __init__(self,name):
        self.name = name
    def __getattribute__(self, item):
        return super(Person, self).__getattribute__(item) # 复杂写法
        return super().__getattribute__(item)  # 简便写法

obj  = Person('把我删啦')
print(obj.__getattribute__('name'))
'''__exit__ :对象被with语法执行并运行完with子代码之后自动触发
def __exit__(self, exc_type, exc_val, exc_tb):对象被with语法执行并运行完with子代
码之后 自动触发'''

class Open:
    def __init__(self,name):
        self.name=name
    def __enter__(self):
        print('对象被with语法执行的时候自动触发 该方法返回什么 as关键字后面的变量名就能得到什么')
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('对象被with语法执行并运行完with子代码之后 自动触发')

with Open('a.txt') as f:
    print(f)

元类简介

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

创建类的两种方式

1.class关键字       

class Person :
     pass

2.利用元类type

class MyMetaClass(type):
    pass
class MyClass(metaclass = MyMetaClass)
    pass

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

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

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

class MyMetaClass(type):
    def __init__(self,what, bases=None, dict=None): 
# what 类名 
# bases 父类 
# dict 类的名称空间
        if not what.istitle():
            raise Exception('首字母必须大写')
        super().__init__(what, bases, dict)

class person(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('aa', 88)
# 当参数没有用关键字传参的时候会报错

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

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

元类之双下new方法

1.new方法的作用:

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

2.具体用法:

class Person(object):
    def __init(self,*args,**kwargs):
        print('init')
    def __new__(cls,*args,**kwargs):
        print('new')
        print(type(cls))
obj = Person()

'''打印结果
new
<class 'type'>
'''

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值