标签:筛选 父类 print people 字典 main == 文档 error
目录
__call__
方法控制对象的产生# 定义一个类
class Foo(object): # python3中默认继承object类
count = 0
def __init__(self,name,age):
self.name = name
self.age = age
@property
def func(self):
print('from func')
f1 = Foo('hades',27)
print(f1.__dict__)
f1.func
{'name': 'hades', 'age': 27}
from func
exec会把字符串按照python语法解析成代码,把解析完的代码放入字典中
s = '''
count = 0
def __init__(self,name,age):
self.name = name
self.age = age
def func(self):
print('from func')
'''
dic = dict()
exec(s,{},dic)
print(dic)
{'count': 0, '__init__': <function __init__ at 0x0000023CB5544C80>, 'func': <function func at 0x0000023CB55FD378>}
# 1. 类名
class_name = 'Foo'
# 2. 类体代码(需要按照python语法规则)
class_body = '''
count = 0
def __init__(self,name,age):
self.name = name
self.age = age
@property
def func(self):
print('from func')
'''
# 3. 基类(父类)
class_bases =(object,) # 必须加逗号,形成一个元组
class_dict = dict()
exec(class_body, {}, class_dict) # 产生类体名称空间
print(class_dict)
{'count': 0, '__init__': <function __init__ at 0x0000023CB56842F0>, 'func': <property object at 0x0000023CB56773B8>}
Foo1 = type(class_name, class_bases, class_dict)
print(Foo1)
<class '__main__.Foo'>
f2 = Foo1('hades', 27)
print(f2.__dict__)
f2.func
{'name': 'hades', 'age': 27}
from func
这样我们就生成了一个类
class Mymeta(type): # 只有继承了type类才能称之为一个元类,否则就是一个很普通的类
def __init__(self, class_name, class_bases, class_dict):
print(class_name)
print(class_bases)
print(class_dict)
super().__init__( class_name, class_bases, class_dict) # 使用父类功能生成一个类对象
print('创建类成功了')
分析用class自定义类的运行原理(而非元类的的运行原理):
1.拿到一个字符串格式的类名class_name = ‘Foo‘
2.拿到一个类的基类们class_bases = (obejct,)
3.执行类体代码,拿到一个类的名称空间class_dict={...}
4.调用Foo1 = type(class_name, class_bases, class_dict)
class Foo(metaclass=Mymeta): # python3中默认继承object类
count = 0
def __init__(self,name,age):
self.name = name
self.age = age
@property
def func(self):
print(f'name "{self.name}" from func')
Foo
()
{'__module__': '__main__', '__qualname__': 'Foo', 'count': 0, '__init__': <function Foo.__init__ at 0x0000023CB5684D08>, 'func': <property object at 0x0000023CB5690368>}
创建类成功了
f1 = Foo('Bonnie',16)
f1.func
name "Bonnie" from func
自定义元类控制类的产生过程,类的产生过程其实就是元类的调用过程
我们可以控制类必须有文档,类名首字母要大写,可以使用如下的方式实现
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dict):
if not class_name.istitle():
raise TypeError('类名首字母要进行大写')
if (not class_dict.get('__doc__')) or len(class_dict['__doc__']) == 0:
raise TypeError("必须有文档注释")
super().__init__( class_name, class_bases, class_dict)
# 类名首字母没有大写
try:
class foo(metaclass=Mymeta):
def __init__(self,name,age):
self.name = name
self.age = age
except Exception as e:
print(e)
类名首字母要进行大写
# 没有注释
try:
class Foo(metaclass=Mymeta):
def __init__(self,name,age):
self.name = name
self.age = age
except Exception as e:
print(e)
必须有文档注释
try:
class Foo(metaclass=Mymeta):
"""测试文件"""
def __init__(self,name,age):
self.name = name
self.age = age
f1 = Foo('hades',20)
print(f1.__dict__) # {'name': 'hades', 'age': 20}
except Exception as e:
print(e)
{'name': 'hades', 'age': 20}
可以通过__call__
方法进行实现
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dict):
if not class_name.istitle():
raise TypeError('类名首字母要进行大写')
if (not class_dict.get('__doc__')) or len(class_dict['__doc__']) == 0:
raise TypeError("必须有文档注释")
super().__init__( class_name, class_bases, class_dict)
def __call__(self,*args,**kwargs):
print(self)
print(args)
print(kwargs)
obj = self.__new__(self)
self.__init__(obj,*args,**kwargs)
print(obj)
return obj
class Foo(metaclass=Mymeta):
"""测试文件"""
def __init__(self,name,age):
self.name = name
self.age = age
f1 = Foo('Bonnie',18)
print(f1)
print(f1.__dict__)
<class '__main__.Foo'>
('Bonnie', 18)
{}
<__main__.Foo object at 0x0000023CB56B4048>
<__main__.Foo object at 0x0000023CB56B4048>
{'name': 'Bonnie', 'age': 18}
类的调用,即类实例化就是元类的调用过程,可以通过元类Mymeta的__call__方法控制
分析:调用Pepole的目的
先造出一个People的空对象
为该对空对象初始化独有的属性
返回一个初始化好的对象
标签:筛选 父类 print people 字典 main == 文档 error
原文地址:https://www.cnblogs.com/Hades123/p/11068350.html