Discuss / Python / 我有个问题理解不了,希望有人能帮我解答

我有个问题理解不了,希望有人能帮我解答

在编写ORM框架的过程中,定义了find方法,但是我调用该方法时,没有办法输出其中print语句的内容。方法定义如下:

    @classmethod
    @asyncio.coroutine
    def find(cls,pk):
        print('find function')
        ' find object by primary key. '
        rs = yield from select('%s where %s=?' % (cls.__select__, cls.__primary_key__), [pk], 1)
        if len(rs) == 0:
            return None
        return cls(**rs[0])

使用User.find('123')调用,但是控制台没有输出"find function",求解释,因为我自己没办法理解为何没有输出 下面我贴上所有代码,可能有点杂...

import logging
import asyncio
import aiomysql

@asyncio.coroutine
def creat_pool(loop,**kw):
    print("creat database connection pool...")
    global __pool
    _pool = yield from aiomysql.creat_pool(
        host=kw.get("post","localhost"),
        port=kw.get("port",3306),
        user=kw['user'],
        password=kw['password'],
        db=kw['db'],
        charset=kw.get('charset','utf8'),
        autocommit=kw.get('autocommit',True),
        maxsize=kw.get('maxsize',10),
        minsize=kw.get('minsize',1),
        loop=loop
    )

########################################################################定义元类,通过元类来动态创建类########################################################################   
class ModelMetaclass(type):
    def __new__(cls,name,bases,attrs):
        #logging.info("New Class %s with name %s from parent Class %s ,and the attrs are %s" %(cls,name,bases,attrs))
        #排除Model类本身
        if name=='Model':
            return type.__new__(cls,name,bases,attrs)
        #获取table名称
        tableName=attrs.get('__table__',None) or name
        #logging.info('found model: %s (table: %s)'%(name,tableName))
        #获取所有的Field和主键名
        mappings = dict()
        fields = []
        primaryKey = None
        for k,v in attrs.items():
            if isinstance(v,Field):
                #logging.info('found mapping:%s ==>%s'% (k,v))
                mappings[k] = v
                if v.primary_key:
                    #找到主键
                    if primaryKey:
                        raise RuntimeError("Duplicated primary key for field :%s" % k)
                    primaryKey = k
                else:
                    fields.append(k)
        if not primaryKey:
            raise RuntimeError('Primary key not found')
        for k in mappings.keys():
            attrs.pop(k)

        escaped_fields = list(map(lambda f: '%s' % f, fields))                          #map函数的应用,对fields中的每个元素使用lambda方法
        attrs['__mappings__'] = mappings # 保存属性和列的映射关系
        attrs['__table__'] = tableName
        attrs['__primary_key__'] = primaryKey # 主键属性名
        attrs['__fields__'] = fields # 除主键外的属性名


        # 构造默认的SELECT, INSERT, UPDATE和DELETE语句:
        attrs['__select__'] = 'select %s, %s from %s' % (primaryKey, ', '.join(escaped_fields), tableName)

        valueList = []
        for f in escaped_fields:
            for k in mappings:
                if k==f:
                    valueList.append(mappings[k])
        valueList.append(mappings[primaryKey])

        attrs['__insert__'] = 'insert into %s (%s, %s) values (%s)' % (tableName, ', '.join(escaped_fields), primaryKey, valueList)  #这里的值不一定是对的
        attrs['__update__'] = 'update %s set %s where %s=?' % (tableName, ', '.join(map(lambda f: '`%s`=?' % (mappings.get(f).name or f), fields)), primaryKey)
        attrs['__delete__'] = 'delete from %s where %s=?' % (tableName, primaryKey)
        return type.__new__(cls, name, bases, attrs)


########################################################################定义Model类########################################################################
class Model(dict,metaclass=ModelMetaclass):
    def __init__(self,**kw):
        print('Enter Model')
        super(Model,self).__init__(**kw)

    def __getattr__(self,key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Model' Object has no attribute '%s'" % key)

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

    def getValue(self,key):
        print('getValue')
        return getattr(self,key,None)

    def getValueOrDefault(self,key):
        value=getattr(self,key,None)
        if value is None:
            field = self.__mapping__[key]
            if value is None:
                field = self.__mapping__[key]
                if field.default is not None:
                    value = field.default() if callable(field.default) else field.default
                    logging.debug('using default value for %s:%s'% (key,str(value)))
                    setattr(self,key,value)
        return value

    @classmethod
    @asyncio.coroutine
    def find(cls,pk):
        print('find')
        ' find object by primary key. '
        rs = yield from select('%s where %s=?' % (cls.__select__, cls.__primary_key__), [pk], 1)
        if len(rs) == 0:
            return None
        return cls(**rs[0])

    @classmethod 
    @asyncio.coroutine
    def findAll(cls,pks):
        print('findAll')

    @asyncio.coroutine
    def save(self):
        logging.info('save')
        args = list(map(self.getValueOrDefault, self.__fields__))
        args.append(self.getValueOrDefault(self.__primary_key__))
        rows = yield from execute(self.__insert__, args)
        if rows != 1:
            logging.warn('failed to insert record: affected rows: %s' % rows)


    @asyncio.coroutine
    def select(sql,args,size=None):
        print('select')
        log(sql,args)
        global __pool
        with(yield from __pool) as conn:
            cur = yield from conn.cursor(aiomysql.DictCursor)
            yield from cur.execute(sql.replace('?','%s'),args or ())
            if size:
                rs = yield from cur.fetchmany(size)
            else:
                rs = yield from cur.fetchall()
            yield from cur.close()
            loggin.info('rows returned:%s'% len(rs))
            return rs


    @asyncio.coroutine
    def execute(sql,args):
        log(sql)
        with(yield from __pool) as conn:
            try:
                cur = yield from conn.cursor()
                yield from cur.execute(sql.replace('?','%s'),args)
                affected = cur.rowcount
                yield from cur.close()
            except BaseException as e:
                raise
            return affected

###################################################################################定义值类型基类##########################################################            
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

    def __str__(self):
        return '<%s, %s:%s>' % (self.__class__.__name__, self.column_type, self.name)

###########################################################################定义字符串类################################################################        
class StringField(Field):
    def __init__(self, name=None, primary_key=False, default=None, ddl='varchar(100)'):
        super().__init__(name, ddl, primary_key, default)

###################################################################定义整数值类######################################################################
class IntegerField(Field):
    def __init__(self,name=None,ddl='bigint',primary_key=False,default=None):
        super().__init__(name,ddl,primary_key,default)


class User(Model):
    __table__ = 'users'

    id=IntegerField(primary_key = True)
    name = StringField()

#创建实例    
userMichale = User(id=123,name='Michale')
print(userMichale.getValue('id'))
#存入数据库
user = User.find('123')
#查询所有User对象
users = User.findAll()

userMichale.save()

廖雪峰

#2 Created at ... [Delete] [Delete and Lock User]

协程必须用yield from调用


  • 1

Reply