首页 > 编程语言 >面向对象编程(四)

面向对象编程(四)

时间:2022-11-08 19:11:29浏览次数:37  
标签:__ obj name self 面向对象编程 print def

面向对象编程(四)

一、面向对象的魔法方法

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.单例模式
	类加括号无论执行多少次永远只会产生一个对象
 	目的:
        当类中有很多非常强大的方法 我们在程序中很多地方都需要使用
        如果不做单例 会产生很多无用的对象浪费存储空间

标签:__,obj,name,self,面向对象编程,print,def
From: https://www.cnblogs.com/zx0524/p/16870840.html

相关文章

  • 14.面向对象编程
    1.初识面向对象想要通过面向对象去实现某个或某些功能时需要2步:定义类,在类中定义方法,在方法中去实现具体的功能。实例化类一个对象,通过对象去调用并执行方法。c......
  • 13. Java 面向对象编程
    Java面向对象编程Java的核心思想就是OOP1.初识面向对象面向过程&面向对象面向过程思想步骤清晰简单,第一步做什么,第二步做什么.....面对过程适合处理一些......
  • 狂神说java基础——面向对象编程
    面向对象编程(oop)1、什么是面向对象(00)面向过程:线性思维面向对象:分类思维​ 本质:以类的方式组织代码,以对象的形式阻止(封装)数据三大特性:封装,继承,多态2、回顾方......
  • 面向对象编程 多态
    多态静态多态性,重载重载:同一个方法中有多个相同名称的方法,但参数不一样。在编译阶段(程序未运行的时候),函数之间就产生了一对一的关系。减少函数的命名,多个相同的函数可......
  • 面向对象编程二
    动静态方法1.什么是动态和静态动态就是绑定给对象的方法直接在类体代码中编写即可,对象调用会自动将对象当做第一个参数传入,类调用则有几个形参就传几个实参;静态方法就是......
  • 面向对象编程(二)
    面向对象编程(二)一、动静态方法什么是动静态?动态就是绑定给对象的方法直接在类体代码中编写即可,对象调用会自动将对象当做第一个参数传入,类调用有几个形参就传几个实参;......
  • 面向对象编程
    内容概要面对对象核心思路编程思想面向对象之类与对象类与对象的创建对象独有的数据(属性)对象独有的功能(方法)面对对象核心思路我们如果没有对象的存在,我们有一些......
  • 面向对象编程
    面向对象编程一、面向对象之人狗大战'''推导思路:1.代码定义出人和狗2.将产生人和狗的字典封装成函数3.定义人打狗的动作,和狗咬人的动作(生命值=攻击力-生命值)4.解......
  • 面向对象编程
    1.对象Object对象的两个部分:属性、行为面向对象编程的三大特点:封装、继承、多态2.封装写程序的时候也可以采用封装的理念,对于一些内容我们不提供接口来使用它们,它们属......
  • 05面向对象编程
    对象的创建分析//面向对象编程本质:以类的方式组织代码,以对象的组织(封装)数据面向对象三大特性抽象类和接口内部类及OOP实战......