1 Python创建对象
1.1 Python层面创建对象
"""测试1"""
class Test1(object):
def __new__(cls, *args, **kwargs):
print(f"__new__方法被调用了")
return object.__new__(cls)
t1 = Test1()
# __new__方法被调用了
"""测试2"""
class Test1(object):
def __new__(cls, *args, **kwargs):
print(f"__new__方法被调用了")
return object.__new__(cls)
def __init__(self,name):
print(f'{self}被初始化了')
self.name = name
t1 = Test1('test')
# __new__方法被调用了
# <__main__.Test1 object at 0x000002192A201EB0>被初始化了
如上图所示,通过一个类对象创建一个实例对象,会先调用类对象的__new__方法,__new__方法会接收一个类对象的引用,在堆中开辟一个空间,创建一个对象,返回这个开辟的堆空间引用。
创建好实例之后,类提供__init__方法对实例进行初始化,初始化方法需要一个self参数,self参数就是__new__方法创建的对象,初始化方法在实例内存空间中添加一些属性。
1.2 C源码层面创建对象
暂略
2 元类
Python的对象模型有两种关系,一种是继承关系,另一种是实例化关系,继承关系维护子类与父类之间的联系,实例化关系维护实例与类(模板)之间的关系
继承关系:obj.base
class A:
pass
class B(A):
pass
class C(B):
pass
print(C.__base__)
print(C.__base__.__base__)
print(C.__base__.__base__.__base__)
#<class '__main__.B'>
#<class '__main__.A'>
#<class 'object'>
实例化关系:obj.class
a = 5
print(a.__class__)
print(a.__class__.__class__)
print(a.__class__.__class__.__class__)
#<class 'int'>
#<class 'type'>
#<class 'type'>
本文不过多说继承关系,主要说实例化关系,实例是通过类实例化产生的,这个是很好理解的,Python一切皆对象,类是通过什么创造出来的呢?通过上面的代码执行结果可以看到,类是通过type类创建的,type类也叫元类,type类也是通过type创建出来的。
type类定义在Python源码的builtins.py模块中
2.1 Python层面类如何被创建
class A(object):
A_ = 'I am a class!'
def show(self):
print(self.A_)
def show(self):
print(self.B_)
B = type('B', (object,), {'B_': 'I am B class!', 'show': show})
print(A)
print(B)
A().show()
B().show()
#<class '__main__.A'>
#<class '__main__.B'>
#I am a class!
#I am B class!
当使用class语法糖创建一个对象时,其实在Python内部执行的是type(),Python真的足够灵活,他的动态性真的太好了
2.2 给类加”装饰器“
如果你想不改变函数时增加一个功能,那么毫无疑问的会想到装饰器,当你想规范类的行为时,就可以应用元类,python的类默认都是通过typ类创建出来的,自定义一个类如果继承了type,那么这个类就可以做为一个元类,规范很多类。
元类创造类
class UpperAttrType(type):
"""
因为继承了元类,UpperAttrType可以做为其他类的元类
"""
pass
class A(object,metaclass=UpperAttrType):
"""
class A 继承 object
UpperAttrType为A类的元类
"""
pass
print(A.__class__)
# <class '__main__.UpperAttrType'>
元类创造类的过程
class UpperAttrType(type):
"""
因为继承了元类,UpperAttrType可以做为其他类的元类
"""
def __new__(cls, *args, **kwargs):
print('我被执行了')
__mapping__ = dict()
for i in args:
if isinstance(i,dict):
for k,v in i.items():
if not str(k).startswith('__'):
__mapping__[str(k).upper()] = v
return type('A',(),__mapping__)
class A(object,metaclass=UpperAttrType):
"""
class A 继承 object
UpperAttrType为A类的元类
"""
age = 11
a = A()
print(hasattr(a,'age'))
# False
print(hasattr(a,'AGE'))
# True
创建类,第一步是执行元类的__new__方法,__new__方法要返回一个类,在返回的过程中对类属性进行修改,类似函数的装饰器。
3 元类的应用->ORM
ORM (object relationship mapping),对象关系映射,在django和sqlalchemy中都实现了ORM框架
在应用中使用sql语句对数据库进行操作会比较麻烦,如果使用类和对象对数据库进行操作,就会免去写大量的SQL语句。
V1.0
class ModelMateClass(type):
def __new__(cls, name, bases, attrs):
__mapping__ = dict()
for k, v in attrs.items():
if isinstance(v, tuple):
__mapping__[k] = v
for k in __mapping__.keys():
attrs.pop(k)
attrs['mapping'] = __mapping__
attrs['__tablename__'] = name
return type.__new__(cls, name, bases, attrs)
class User(metaclass=ModelMateClass):
uid = ('uid', 'unsigned int')
name = ('username', 'varchar(30)')
email = ('email', 'varchar(30)')
password = ('password', 'varchar(30)')
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
def save(self):
fields = [k for k, v in User.mapping.items()]
tags = [v for k, v in self.__dict__.items()]
sql = f'insert into %s (%s) values (%s)' % (User.__tablename__, ','.join(fields), ','.join(tags))
print(sql)
u1 = User(uid="1", name="zs", email="xxx@xx.com", password="123")
u1.save()
# insert into User (uid,name,email,password) values (1,zs,xxx@xx.com,123)
V1.1
#升级save
def save(self):
fields = [k for k, v in User.mapping.items()]
tags = [v for k, v in self.__dict__.items()]
tags_ = []
for tag in tags:
if isinstance(tag, int):
tags_.append(f"""{tag}""")
elif isinstance(tag, str):
tags_.append(f"""'{tag}'""")
sql = f'insert into %s (%s) values (%s)' % (User.__tablename__, ','.join(fields), ','.join(tags_))
print(sql)
# insert into User (uid,name,email,password) values (1,'zs','xxx@xx.com','123')
V1,2
class Model(metaclass=ModelMateClass):
pass
class User(Model):
uid = ('uid', 'unsigned int')
name = ('username', 'varchar(30)')
email = ('email', 'varchar(30)')
password = ('password', 'varchar(30)')
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
def save(self):
fields = [k for k, v in User.mapping.items()]
tags = [v for k, v in self.__dict__.items()]
tags_ = []
for tag in tags:
if isinstance(tag, int):
tags_.append(f"""{tag}""")
elif isinstance(tag, str):
tags_.append(f"""'{tag}'""")
sql = f'insert into %s (%s) values (%s)' % (User.__tablename__, ','.join(fields), ','.join(tags_))
print(sql)
class Book(Model):
bookid = ('bookid', 'unsigned int')
name = ('bookname', 'varchar(30)')
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
def save(self):
fields = [k for k, v in Book.mapping.items()]
tags = [v for k, v in self.__dict__.items()]
tags_ = []
for tag in tags:
if isinstance(tag, int):
tags_.append(f"""{tag}""")
elif isinstance(tag, str):
tags_.append(f"""'{tag}'""")
sql = f'insert into %s (%s) values (%s)' % (Book.__tablename__, ','.join(fields), ','.join(tags_))
print(sql)
封装之后的样子是不是感觉很眼熟