设为首页 收藏本站
查看: 818|回复: 0

[经验分享] Python Trick 两条: 如何还原函数的参数调用+元类与缓存

[复制链接]

尚未签到

发表于 2017-5-8 11:42:55 | 显示全部楼层 |阅读模式
  ##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)
                    )
            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)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-374653-1-1.html 上篇帖子: 解决在Leopard下irb不能输入非ASCII字符问题(python也有效) 下篇帖子: 使用SWIG和Python对C/C++进行单元测试(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表