元类简介
"""推导步骤1:如何查看数据的数据类型"""
s1 = 'hello word '
l1 = [11, 22, 33, 44, 55]
d1 = {'name': 'jason'}
t1 = (11, 22, 33, 44)
print(type(s1)) # <class 'str'>
print(type(l1)) # <class 'list'>
print(type(d1)) # <class 'dict'>
print(type(t1)) # <class 'tuple'>
"""推导步骤2:其实type方法是用来查看产生对象的类名"""
class Student:
pass
obj = Student()
print(type(obj)) # <class '__main__.Student'>
"""推导步骤3:python中一切皆对象,我们好奇type查看类名显示的是什么"""
class Student:
pass
obj = Student()
print(type(obj)) # <class '__main__.Student'>
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 = 'moumou'
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__(cls, what, bases=None, dict=None):
print(cls) # <class '__main__.myclass'>,就是元类产生的类
print(what) # myclass 元类产生的类名
print(bases) # () 类继承的父类,没有继承则为空的元组
print(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__)
元类定制对象的产生行为
"""
推导:
对象加括号会执行该生该对象类里面的__call__
那么类加括号就会执行产生该类的元类里面的__call__
"""
"""给对象添加独有的数据的时候,必须采用关键字参数传参"""
# 先定义一个元类
class MyMetaClass(type):
def __call__(self, *args, **kwargs):
print(2) # 类产生一个对象首先触发元类的__call__
print(args) # ('jason', 18) # args接收元类产生的类产生对象的时候的位置参数
print(kwargs) # {'gender': 'male'} # kwags接收元类产生的类产生对象的时候的关键字参数
if args: # 如果args这个元组存在,证明有位置参数
raise TypeError('必须要求全部都是关键字传参')
print(3) # 触发到这里然后返回给__init__接收
return super().__call__(*args, **kwargs) # 调用元类方法返回
class Student(metaclass=MyMetaClass):
def __init__(self, name, age, gender):
print(1) # 接收元类__call__产生的
self.name = name
self.age = age
self.gender = gender
print(4) # 最后结束,产生一个含有内部独立空间的对象
obj = Student(name='jason', age=18, gender='male')
print(obj.__dict__)
模仿方法之双下new
class MyMetaClass(type):
def __call__(cls, *args, **kwargs):
print(cls) # <class '__main__.Student'>
# 产生一个空对象(骨架)
obj = cls.__new__(cls) # 类在元类中调用__new__()将自己作为参数传入产生一个新的对象
# 类调用__init__给对象添加独有的数据(血肉)
cls.__init__(obj, *args, **kwargs) # 类点__init__给对象添加独立的数据,
return obj # 将对象返回
class Student(metaclass=MyMetaClass):
def __init__(self, name):
self.name = name+
obj = Student('jason')
print(obj.name)
"""
__new__可以产生空对象
"""
设计模式简介
1.设计模式
前人通过大量的验证创建出来解决一些问题的固定高效方法
2.IT行业
23种
创建型
结构型
行为型
ps:课下感兴趣可以简单看看
3.单例模式
类加括号无论执行多少次永远只会产生一个对象
目的:
当类中有很多非常强大的方法 我们在程序中很多地方都需要使用
如果不做单例 会产生很多无用的对象浪费存储空间
我们想着使用单例模式 整个程序就用一个对象
标签:__,元类,面向对象,Student,print,type,class,之元类
From: https://www.cnblogs.com/zhanghong1229/p/16870099.html