推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
explist
V2EX  ›  Python

描述器类中__get__()的疑问

  •  
  •   explist · Nov 30, 2016 · 2074 views
    This topic created in 3589 days ago, the information mentioned may be changed or developed.

    import types

    from functools import wraps

    class profiled:

    def __init__(self,func):
        wraps(func)(self)    
     
    def __call__(self,*a,**k):
        print("profiled.call")        
        return self.__wrapped__(*a,**k)
    
    def __get__(self,instance,cls):
        if instance is None: return self
        foo=types.MethodType(self,instance)
        print("profiled.get:",foo)
        return foo
    

    class spam:

    @profiled
    def bar(self,x):print(x)
    

    if name == 'main':

    s=spam()
    print(s.__dict__,spam.__dict__,'\n')
    f=s.bar
    print(f,type(f),f.__dict__,sep='\n')
    f("TEST")  #f 已经是绑定的方法了,为什么还要调用__call__()
    
    4 replies  •  2016-12-01 22:59:40 +08:00
    explist
        1
    explist  
    OP
       Nov 30, 2016
    输出:
    {} {'__dict__': <attribute '__dict__' of 'spam' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'spam' objects>, '__module__': '__main__', 'bar': <__main__.profiled object at 0x02A8BCF0>}

    profiled.get: <bound method spam.bar of <__main__.spam object at 0x70>>
    <bound method spam.bar of <__main__.spam object at 0x70>>
    <class 'method'>
    {'__annotations__': {}, '__wrapped__': <function spam.bar at 0x10>, '__qualname__': 'spam.bar', '__name__': 'bar', '__module__': '__main__', 'n': 0, '__doc__': None}
    profiled.call
    TEST
    billgreen1
        2
    billgreen1  
       Dec 1, 2016
    因为 f 不是 bar ,而是 wrappered 过的 bar,本质上应该是 profiled 类吧
    explist
        3
    explist  
    OP
       Dec 1, 2016
    看了下 MethodType 的源码,不是很明白这里面的原理:

    class _C:
    def _m(self): pass
    MethodType = type(_C()._m)
    explist
        4
    explist  
    OP
       Dec 1, 2016
    @explist
    type(_c()._m) #这是创建类还是查看类型?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2989 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:13 · PVG 20:13 · LAX 05:13 · JFK 08:13
    ♥ Do have faith in what you're doing.