`
zuroc
  • 浏览: 1292121 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
社区版块
存档分类
最新评论

Python Trick 两条: 如何还原函数的参数调用+元类与缓存

阅读更多

##1.如何还原函数的参数调用
##什么也不说了,copy and run
##有什么用,自己想象吧

def show_para(func):
    func_id="%s.%s"%(func.__module__,func.__name__)
    varnames=func.func_code.co_varnames
   
    if func.func_defaults:
        varnames_len=len(varnames)
        defaults=[repr(i) for i in func.func_defaults]
        def get_id(args,kwds):
            paras=[repr(i) for i in args]
            len_args=len(args)
            pos=len_args-varnames_len
            if kwds:
                for i in varnames[len_args:]:
                    paras.append(
                        repr(kwds.get(i,defaults[pos]))
                    )
                    pos+=1
            else:
                paras.extend(defaults[pos:])
            return "%s(%s)"%(func_id,",".join(paras))[-250:]
    else:
        def get_id(args,kwds):
            paras=[repr(i) for i in args]
            if kwds:
                for i in varnames[len(args):]:
                    paras.append(
                        repr(kwds[i])
                    )
            return "%s(%s)"%(func_id,",".join(paras))[-250:]
           
    def _func(*args,**kwds):
        print get_id(args,kwds)
        print len(get_id(args,kwds))
    return _func
   
@show_para
def xxx(a,b,c,d="张",e="沈",f="鹏",g=2):
    pass

@show_para
def ooo(a,b,c):
    pass
   
xxx(1,2,3,f=121)

ooo(1,2,3)

########################################################################


##2.元类与缓存
#coding:utf-8

##同样,copy and run
##不做解释,自己想象

from types import ClassType
class mc(object):
    __cache={}
   
    @staticmethod
    def get(id):
        r=mc.__cache.get(id,None)
        print "mc.get\t%s = %s"%(id,r)
        return r

    @staticmethod
    def set(id,value):
        print "mc.set\t%s = %s"%(id,value)
        mc.__cache[id]=value

    @staticmethod
    def delete(id):
        print "mc.delete \t%s"%(id)
        mc.__cache.pop(id)


class MetaMc(type):
    """
    使用该元类的类
    如果自定义__init__必须第一个参数必须是id
    否则,生成的__init__第一个参数默认是id
    """
    def __new__(cls,classname,bases,classdict):
        class_id="%s.%s:"%(classdict['__module__'],classname)

        def init_maker(init):
            if init:
                for i in bases:
                    if isinstance(i,MetaMc):
                        def __init__(self,id,*args,**kwds):
                            return init(self,id,*args,**kwds)
                        return __init__
                def __init__(self,id,*args,**kwds):
                    self.__id=int(id)
                    self.__mc_id="%s%s"%(class_id,id)
                    self.__profile=mc.get(self.__mc_id) or {}
                    init(self,id,*args,**kwds)
            else:
                if bases:
                    if isinstance(bases[0],MetaMc):
                        return None
                    else:
                        def __init__(self,id,*args,**kwds):
                            self.__id=int(id)
                            self.__mc_id="%s%s"%(class_id,id)
                            self.__profile=mc.get(self.__mc_id) or {}
                            return bases[0].__init__(self,*args,**kwds)
                else:
                    def __init__(self,id,*args,**kwds):
                        self.__id=int(id)
                        self.__mc_id="%s%s"%(class_id,id)
                        self.__profile=mc.get(self.__mc_id) or {}
            return __init__

        __init__=init_maker(classdict.get("__init__",None))
       
        if __init__:
            classdict["__init__"]=__init__

        @property
        def id(self):
            return self.__id
        classdict["id"]=id

        if "__repr__" not in classdict:
            def __repr__(self):
                return self.__mc_id
            classdict["__repr__"]=__repr__

        if "__str__" not in classdict:
            def __str__(self):
                return self.__mc_id
            classdict["__str__"]=__str__      
 
        def mc_clean(self):
            self.__profile={}
            mc.delete(self.__mc_id)
        classdict["mc_clean"]=mc_clean
       
        def get_maker(k,v):
            def get(self):   
                profile=self.__profile
                   
                if k in profile:
                    result=profile[k]
                else:
                    result=v.get.im_func(self)
                    profile[k]=result
                    mc.set(self.__mc_id,profile)
                    self.__profile=profile
                return result
            return get

        def set_maker(k,v):
            def set(self,value):
                result=v.set.im_func(self,value)
                self.__profile[k]=value
                mc.set(self.__mc_id,self.__profile)
                return result
            return set

        for k,v in classdict.iteritems():
            if isinstance(v,ClassType):
                has_get=hasattr(v,"get")
                has_set=hasattr(v,"set")
                if has_set and has_get:
                    classdict[k]=property(get_maker(k,v),set_maker(k,v))
                elif has_get:
                    classdict[k]=property(get_maker(k,v))
                elif has_set:
                    classdict[k]=property(fset=set_maker(k,v))
               
        return type.__new__(cls, classname, bases, classdict)



class db:
    name=1
    amount=0
   
class A:
    __metaclass__=MetaMc
   
    class name:
        def get(self):
            return db.name
           
        def set(self,value):
            db.name=value
   
    class amount:
        def get(self):
            return "amount %s"%db.amount
        def set(self,value):
            pass

class B(A):
    pass
   
       
b=B(1)
print b.name
print b.name
print b.name
b.name+=1
print b.name
print b.name
b.mc_clean()
print b.name
print b.id
print type(b.id)

4
0
分享到:
评论
1 楼 huangpengxiao 2008-08-18  
晕 你不解释还真看不懂

相关推荐

Global site tag (gtag.js) - Google Analytics