zoukankan      html  css  js  c++  java
  • Python类__call__()方法

    转自: https://www.cnblogs.com/lyu454978790/p/8630215.html

    __call__():Python中,只要在创建类型的时候定义了__call__()方法,这个类型就是可调用的。
    
    Python中的所有东西都是对象,其中包括Int/str/func/class这四类,它们都是对象,都是从一个类创建而来的。元类就是创建这些对象的东西,type就是Python的内建元类。
    
    其中,func是可调用的对象,说明在创建它的类型(父类或它本身)的时候,定义了__call__()方法。
    
    >>>callable(lambda:8)
    
    True
    
    >>>def fn():
    
        pass
    
    >>>callable(fn)
    
    True
    
    所以一个类实例也可以成为类似函数这样能直接调用的对象,只要定义的时候有__call__()方法就可以。
    
    >>>class Reader():
    
        def __init__(self,name,nationality):
    
          self.name = name
    
          self.nationality = nationality
    
        def __call__(self):
    
          print('Reader: %s    Nationality: %s' % (self.name, self.nationality))
    
    >>>r = Reader('Annie','Chinese')
    
    >>>r()
    
    Reader:Annie  Nationality: Chinese
    
    __call__()方法还可以带参数
    
    定义一个可以直接调用类实例的Reader类,并可统计读者数量
    
    >>>class Reader():
    
        count = 0
    
        def __init__(self,name,nationality):
          self.name = name
          self.nationality = nationality
          Reader.count += 1
    
        def __call__(self, behave):
          print('Reader: %s' % self.name)
          print('Nationality: %s' % self.nationality)
          print('%s is being %s.' % (self.name, behave))
          print('The total number of readers is %s.' % Reader.count)
    
    >>>a = Reader('Annie','Chinese')
    
    >>>a('Nice')
    
    Reader: Annie
    
    Nationality: Chinese
    
    Annie is being Nice.
    
    The total number of readers is 1.
    
    >>>b = Reader('Adam','American')
    
    >>>b('Silly')
    
    Reader: Adam
    
    Nationality: American
    
    Adam is being Silly.
    
    The total number of readers is 2.      #自动增加
    

    在类做装饰器的时候也会用到__call__函数,类做装饰器的时候,装饰函数(@类名),就是创建了一个类实例(函数本身是可以直接调用的,但是类做装饰器的时候,函数就被实例化成了一个类对象,而类对象是不能直接调用的),由于类实例是不能直接调用的,如果想直接调用类实例,就要在类中定义__class__()函数
    例如:

    class Test(object):
    
        def __init__(self,func):
            print "func name is %s"%func.__name__ #func.__name__  会调用func所指向的函数名
            self.__func = func #self.__func 被赋予func的引用,即这里的self.__func指向的是test()函数
    
        def __call__(self): #在上面的例子中已经说了,如果类对象调用,会执行__call__函数里的内容,此时self.__func指向test()
    是执行__call__函数
            print "----类做装饰器----"
            self.__func() #因为self.__func指向的是test()函数,所以这里会调用test()函数
    
    @Test #类做装饰器和闭包函数做装饰器是一样的用法,这里的@Test也是相当于test=Test(test),func会接收这个函数名参数,同样在调用前装饰,此时的test指向的是self.__func,而self__func所指向的是func的引用,即是test(),在下面的例子里证明对象是不能直接调用的,但是这里有__call__函数,所以在__call__函数里面调用self.__func函数的时候,等于调用的是test(),这里也是和函数做装饰器所不同的地方 
    def test():
        print "----test----"
    
    test() # 有了__call__函数之后,类实例也可以调用
    
  • 相关阅读:
    像asp.net Mvc一样开发nodejs+express Mvc站点
    js数组方法大全
    自己的时间规划
    7月暑假生活总结
    01. What Is Discrete Mathematics(中英字幕 by Ocean-藏心)
    找工作专题---二分查找
    angular.js 入门基础
    WCF实例管理
    是技术牛人,如何拿到国内IT巨头的Offer
    python
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/9342101.html
Copyright © 2011-2022 走看看