魔法方法 元类

今日内容

面向对象的魔法方法

魔法方法:类中定义的双下方法都称为魔法方法
        不需要认为调用 在特定情况下会自动触发运行
eg:__init__创建空对象之后自动出发给对象添加都有数据
class Student:

    def __init__(self,name,age):
        self.name = name
        self.age = age
    '''对象添加私有数据的时候自动触发'''
    def __str__(self):
        print('hahaha')
        return 'sss'
    '''对象执行打印操作的时候 会自动触发 该方法返回什么 打印结果就是什么
    必须要有返回值 且返回值必须是字符串类型的数据'''
    
    def __call__(self, *args, **kwargs):
        print('哈哈哈')
        print(args,kwargs)
        return '啦啦啦'
    '''可以对象()直接调用 跟函数差不多 也可以用变量名接收他的返回值
    #对象加括号调用的时候直接触发'''

    def __getattr__(self, item):
        print('haha ')
        return 'no'
    '''对象在查找无法使用的名字是自动触发
    item  你想找的没有的名字
    该方法返回什么 点不存在的名字就可以得到什么'''

    def __getattribute__(self, item):
        print('heihei')
    '''对象在查找名字的时候就会触发 有这个了就不会执行上面的那个'''

    def __setattr__(self, key, value):
        print('xiix')
        print(key,value)
    '''key value 是对应的值
    修改数据 obj1.name = 'tom'
    给对象修改或者添加数据的时候自动触发 对象.名字 = 值'''

    def __enter__(self):
        return 888
    '''当对象被当作with上下文管理操作的时候开始自动触发 并且该方法返回什么 as后面的变量名就会接受到什么'''
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('hhhhh')
    '''with 还是那个下文管理语法运行完毕之后自动触发(子代码结束)'''

obj = Student('jason',18)
print(obj)  #<__main__.Student object at 0x00000206C0C43B50> 没有定义__str__方法
print(obj.name)
print(obj)#hahaha  定义了str方法
obj()
res = obj(123,32,153,name='哈哈哈')
print(res)
print(obj.name)
print(obj.hobby)
with obj as f:
    print(f)

魔法方法的笔试题

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):
        return self
 
'''
 with 上下文管理 用__enter__ 和 __exit__
 f 是返回的 对象 对象.名字 定义一个这个名字的功能
'''


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.age = 22
obj.hobby = 'read'

print(obj.name)
'''
定义一个类 继承dict
增加和更改用__srtattr__
可以往字典里面添加键值对
注意 是字典里面不是名称空间里面
取数据用__getarrt__
item是一个不存在的名字 直接取这个不存在的名字 在字典里面取 不用去名称空间中取 就可以直接对象点名字取值了
'''

元类简介

'''推导步骤1:如何查看数据类型'''
l1 = [11,2,3,4,]
s1 = 'hello'
print(type(l1))  #<class 'list'>
print(type(s1))  #<class 'str'>
'''推导步骤2:其实type方法是用来查看产生对象的类名'''
class Student:
    pass
obj=Student()
print(type(obj)) #<class '__main__.Student'>
'''推导步骤3:python中一切皆对象 我们好奇type查看类名显示的是什么'''
class Student:
    pass
obj = Student()
print(type(obj))
print(type(Student)) #<class 'type'>

class A:
    pass
class B:
    pass
print(type(A),type(B))#<class 'type'> <class 'type'>
'''
结论:
  我们定义的类其实都是由type类产生的>>>:元类(产生类的类)
'''

创建类的两种方式

方式1:使用关键字class
class Teacher:
	school_name = '鞠鞠宝贝'
    def func1(self):
        pass
print(Teacher)
print(Teacher__dict__)

方式2:利用元类type type(类名,类的父类,类的名称空间)
cls = type('Student',(object),{'name','jason'})
print(cls)
print(cls.__dict__)
'''
了解知识:名称空间的产生
1.手动写键值对
	针对绑定方法不好定义
2.内置方法exec
	能够运行字符串类型的代码并产生名称空间
'''

元类定制类的产生行为

'''
推导:
  对象是由类名加括号产生的   __init__
  类是由元类加括号产生的    __init__
'''
#1.自定义元类:继承type的类也称之为元类
''' 所有的类必须首字母大写 否则无法产生'''
class MyMetaClass(type):
    def __init__(self,what, bases=None, dict=None):
        # print(what)
        # #类名
        # print(bases)
        # #类继承的父类
        # print(dict)
        #名称空间中的名字
        if  not what.istitle():
            raise TypeError('类名首字母要大写')
        super().__init__(what, bases, dict)

#2.指定类的元类:利用metaclass指定类的元类
class Myclass(metaclass=MyMetaClass):
    deac = 'hahahahha'
class Student(metaclass=MyMetaClass):
    info = '我是学生 我很听话'
print(Student)
print(Student.__dict__)

元类定制对象的产生行为

'''
推导
  对象加括号会执行产生该对象类里面的  __call__
  类加括号会执行产生该类的类里面的   __call__
'''
'''给数据添加独有参数的时候 必须采用关键字参数传参'''
class MyMetaClass(type):
    def __call__(self, *args, **kwargs):
        #1.产生一个空对象
        #2.调用__init__给对象添加独有的数据
        #3.返回创建好的对象
        #args 多余的位置形参
        #kargs 关键字参数
        if args:
            raise TypeError('要求独享里面的都有数据必须按照关键字传参')
        return super().__call__(*args, **kwargs)

class Student(metaclass=MyMetaClass):
    def __init__(self,name,age,hobby):
        self.name = name
        self.age = age
        self.hobby = hobby

# obj = Student('jason',20,'read')   #位置参数
obj = Student(name='jason',age=20,hobby='read')
print(obj.__dict__)

魔法方法之双下new

class MyMetaClass(type):
    def __call__(self, *args, **kwargs):
        #1.产生一个空对象
        obj = self.__new__(self)
        #2.调用__init__方法给对象添加独有的数据
        self.__init__(obj,*args, **kwargs)
        #3.返回创建好的对象
        return obj

class Student(metaclass=MyMetaClass):
    def __init__(self,name):
        self.name = name

obj = Student('jason')
print(obj.name)
'''
__new__可以产生空对象
'''

设计模式简介

1.设计模式
	前人通过大量的验证创建出来解决一些问题的固定高效方法
2.IT行业
	23种
    	创建型
        结构型
        行为型
3.单例模式
	类加括号无论执行多少次永远只会产生一个对象
    目的:
    	当类中有有很多非常强大的方法 我们在程序中很多地方都需要使		 用 如果不做单例 会产生很多无用的对象浪费内存空间
        我们想着使用单例模式 整个程序就用一个对象
        
posted @ 2022-11-08 20:50  李李大冒险  阅读(26)  评论(0编辑  收藏  举报
  1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 迷人的危险3 FAFA
  4. 4 山楂树之恋 程佳佳
  5. 5 summertime cinnamons / evening cinema
  6. 6 不谓侠(Cover 萧忆情Alex) CRITTY
  7. 7 神武醉相思(翻自 优我女团) 双笙(陈元汐)
  8. 8 空山新雨后 音阙诗听 / 锦零
  9. 9 Wonderful U (Demo Version) AGA
  10. 10 广寒宫 丸子呦
  11. 11 陪我看日出 回音哥
  12. 12 春夏秋冬的你 王宇良
  13. 13 世界が终わるまでは… WANDS
  14. 14 多想在平庸的生活拥抱你 隔壁老樊
  15. 15 千禧 徐秉龙
  16. 16 我的一个道姑朋友 双笙(陈元汐)
  17. 17 大鱼 (Cover 周深) 双笙(陈元汐)
  18. 18 霜雪千年(Cover 洛天依 / 乐正绫) 双笙(陈元汐) / 封茗囧菌
  19. 19 云烟成雨(翻自 房东的猫) 周玥
  20. 20 情深深雨濛濛 杨胖雨
  21. 21 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  22. 22 斑马斑马 房东的猫
  23. 23 See You Again Wiz Khalifa / Charlie Puth
  24. 24 Faded Alan Walker
  25. 25 Natural J.Fla
  26. 26 New Soul Vox Angeli
  27. 27 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  28. 28 像鱼 王贰浪
  29. 29 Bye Bye Bye Lovestoned
  30. 30 Blame You 眠 / Lopu$
  31. 31 Believer J.Fla
  32. 32 书信 戴羽彤
  33. 33 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  34. 34 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  35. 35 慢慢喜欢你 LIve版 戴羽彤
  36. 36 病变 戴羽彤
  37. 37 那女孩对我说 (完整版) Uu
  38. 38 绿色 陈雪凝
  39. 39 月牙湾 LIve版 戴羽彤
像鱼 - 王贰浪
00:00 / 04:45
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好