Python之__new__

__new__为Python中的创建实例函数(在实例化类时,开辟一个空间)

类加括号实例化对象的步骤

1, 创建一个该类的空对象   __new__

2, 实例化该空对象  __init__

3, 将实例化的空对象返回  return cls

 

重写__new__

1. 该方法是从type中继承来的,所以参数同type的init

2. 最终的工作(如果开辟空间,如果操作内存)还是要借助type

3. 再交给type最终完成工作之前,可以对垒的创建加以限制

class MyMetaClass(type):   # 要重写init必须继承type
    def __new__(self, class_name, class_bases, class_addrs):
        print(class_name)  # 类名
        print(class_bases)  # 继承的基类
        print(class_addrs)  # 名称空间
     super().__init__(class_name, class_bases, class_addrs) # 最终还是要借助type class Foo(metaclass=MyMetaClass): def __init__(self): pass obj = Foo() # Foo = MyMetaClass(class_name, class_bases, class_addrs)

'''

  Foo
  ()
  {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x032D8738>}

'''

案例一

from connect_mysql import Mysql


class Field(object):
def __init__(self,name, column_type, primary_key, default):
self.name = name
self.column_type = column_type
self.primary_key = primary_key
self.default = default


class StringField(Field):
def __init__(self,name, column_type='varchar(255)', primary_key=False, default=None):
super().__init__(name,column_type,primary_key,default)


class IntegerField(Field):
def __init__(self,name, column_type='int', primary_key=False, default=None):
super().__init__(name,column_type,primary_key,default)


class MyMetaClass(type):
def __new__(cls, class_name, class_bases, class_addrs):
if class_name == 'Models': return type.__new__(cls, class_name, class_bases, class_addrs)
table_name = class_addrs.get('table_name', class_name)
primary_key = None
mappings = {}
for k,v in class_addrs.items():
if isinstance(v, Field):
mappings[k] = v
if v.primary_key:
if primary_key:
raise TypeError('最多只能拥有一个主键!!!')
primary_key = k
if not primary_key:
raise TypeError('必须拥有一个主键!!!')
for k in mappings.keys():
class_addrs.pop(k)
class_addrs['primary_key'] = primary_key
class_addrs['mappings'] = mappings
class_addrs['table_name'] = table_name
return type.__new__(cls, class_name, class_bases, class_addrs)


class Models(dict, metaclass=MyMetaClass):
def __init__(self, **kwargs):
super().__init__(**kwargs)

def __getattr__(self, item):
return self.get(item, '暂无此键!!!')

def __setattr__(self, key, value):
self[key] = value

@classmethod
def select(cls, **kwargs):
conn = Mysql()
if not kwargs:
sql = 'select * from %s'%cls.table_name
res = conn.select(sql)
else:
key = list(kwargs.keys())[0]
value = kwargs[key]
sql = 'select * from %s where %s = ?'%(cls.table_name, key)
sql = sql.replace('?','%s')
res = conn.select(sql, value)
print(sql)
if res:
return [cls(**r) for r in res]

def update(self):
# sql = 'update user set name='dsada',age='dasd' where id = '1''
conn = Mysql()
primary_key = None
keys = []
values = []
for k,v in self.mappings.items():
if v.primary_key:
primary_key = getattr(self, v.name, v.default)
else:
keys.append(v.name + '=?')
values.append(getattr(self, v.name, v.default))
sql = 'update %s set %s where %s = %s'%(self.table_name, ','.join(keys), self.primary_key, primary_key)
sql = sql.replace('?', '%s')
print(sql)
print(values)
conn.execute(sql, values)

def save(self):
# sql = 'insert into user(name,age) value ('dasd','dada)'
conn = Mysql()
keys = []
values = []
args = []
for k,v in self.mappings.items():
if not v.primary_key:
keys.append(v.name)
values.append(getattr(self, v.name, v.default))
args.append('?')
sql = 'insert into %s(%s) value (%s)'%(self.table_name, ','.join(keys), ','.join(args))
print(sql)
print(values)
sql = sql.replace('?', '%s')
conn.execute(sql, values)



if __name__ == '__main__':
class User(Models):
id = IntegerField(name='id',primary_key=True)
name = StringField(name='name')
password = StringField(name='password')
is_vip = IntegerField(name='is_vip')
is_locked = IntegerField(name='is_locked')
user_type = StringField(name='user_type')
register_time = StringField(name='register_time')

obj = User(name='dasd',password='dasd',is_vip=0,is_locked=0,user_type='admin',register_time='2019-05-27 09:42:33')
obj.save()

猜你喜欢

转载自www.cnblogs.com/yuyafeng/p/10957839.html