面向对象编程(四)

一、面向对象的魔法方法

1.魔法方法简介

  在类中,有一些内置好的特定的方法,方法名是“__xx__”,在进行特定的操作时会被调用,这些方法被称为魔法方法,不需要人为调用 在特定的条件下回自动触发运行	

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)
 

3.魔法方法笔试题

1.补全下列代码使得不报错
class Context:
        pass
    with Context() as f:
        f.do_something()
 
class Context:
    def do_something(self):
        pass
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass
with Context() as f:
    f.do_something()
2.自定义字典类型并让字典能够通过句点符的方式操作键值对
	class MyDict(dict):
        def __setattr__(self, key, value):
            self[key] = value

        def __getattr__(self, item):
            return self.get(item)
        obj = MyDict()
        obj.name = 'jason'
        obj.pwd = 18
        obj.hobby = 'read'
        # print(obj)
        print(obj.name)
        print(obj.pwd)
        print(obj.hobby)
        # print(obj)
        # print(obj)  # 字典存储的数据  {}
        # print(obj.__dict__)  # 字典对象名称空间  {'name': 'jason'}

        print(type(obj))

二、元类简介

所有的对象都是实例化或者通过调用类得到的,python中一切皆对象,通过class关键字定义的类本质也是对象,对象又是通过调用类得到的,因此通过class关键字定义的类肯定也是调用了一个类得到的,这个类就是元类。
"""结论:我们定义的类其实都是由type类产生的>>>:元类(产生类的类)"""

三、创建类的两种方式

1.使用关键字class

class Teacher:
    school_name = '芜湖大学'
    def func1(self):
        pass
print(Teacher)
print(Teacher.__dict__)
# <class '__main__.Teacher'>
{'__module__': '__main__', 'school_name': '芜湖大学', 'func1': <function Teacher.func1 at 0x00000213C5AD7790>, '__dict__': <attribute '__dict__' of 'Teacher' objects>, '__weakref__': <attribute '__weakref__' of 'Teacher' objects>, '__doc__': None}

2.利用元类type type(类名,类的父类,类的名称空间)

cls = type('Student', (object,), {'name':'jason'})
print(cls)
print(cls.__dict__)
# <class '__main__.Student'>
{'name': 'jason', '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

四、元类定制类的产生行为

# 1.自定义元类:继承type的类也称之为元类
class MyMetaClass(type):
    def __init__(self, what, bases=None, dict=None):
        # print('what', what)
        # print('bases', bases)
        # print('dict', dict)
        if not what.istitle():
            raise TypeError('类名首字母应该大写啊!!!')
        super().__init__(what, bases, dict)

# 2.指定类的元类:利用关键字metaclass指定类的元类
class myclass(metaclass=MyMetaClass):
    desc = '元类其实很有趣 '

class Student(metaclass=MyMetaClass):
    info = '我很听话'
print(Student)
print(Student.__dict__)

五、元类定制对象的产生行为

class MyMetaClass(type):
    def __call__(self, *args, **kwargs):
        # 1.产生一个空对象(骨架)
        # 2.调用__init__给对象添加独有的数据(血肉)
        # 3.返回创建好的对象
        # print(args)  # ('jason', 18, 'male')
        # print(kwargs)  # {}
        if args:
            raise TypeError("对象的独有数据必须按照关键字参数传参!!!")
        return super().__call__(*args, **kwargs)
class Student(metaclass=MyMetaClass):
    def __init__(self, name, age, gender):
        # print('__init__')
        self.name = name
        self.age = age
        self.gender = gender
# obj = Student('jason', 18, 'male')
obj = Student(name='jason',age= 18,gender= 'male')
print(obj.__dict__)
类中的__init__用于实力化对象
元类中的__init__用于实例化类
ps:只有继承了type的类才可以称之为是元类,如果想要切换产生类的元类不能使用继承需要使用关键字metaclass声明
ps:如果我们想控制对象的产生过程 可以操作元类里的__call__
    如果我们想控制类里的产生过程 可以操作元类里的__init__

六、魔法方法之双下new方法

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'>
'''

七、设计模式简介及单例模式

1.设计模式
	前人通过大量的验证创建出来解决一些问题的固定高效方法
2.IT行业
	23种
        创建型
        结构型
        行为型
3.单例模式
	类加括号无论执行多少次永远只会产生一个对象
 	目的:
        当类中有很多非常强大的方法 我们在程序中很多地方都需要使用
        如果不做单例 会产生很多无用的对象浪费存储空间

原文地址:http://www.cnblogs.com/zx0524/p/16870840.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性