美文网首页
31.2-魔术方法—可调用对象

31.2-魔术方法—可调用对象

作者: BeautifulSoulpy | 来源:发表于2019-12-27 18:07 被阅读0次

    很多时候我们埋怨生命无法重来,其实你想过没有,如果它可以重来,又有谁会珍惜它;
    如果你相信命,那么一切的偶然都是注定。如果你不相信命,那么一切的注定都是偶然;


    总结:

    1. Python从call中演化了很多独特的写法,这是其他语言中所没有的;

    Python中一切皆对象,函数也不例外。

    如何把一个类的对象当成普通函数来调用呢?

    在Python中,可以通过运算符重载来实现。Python的运算符重载通过特殊的命名来完成。其中,call方法将对象变成一个可调用的对象。只要在类中实现了_call_ 方法,我们就可以像普通函数那样调用一个类对象了。

    # 1. 函数是可 call 对象;
    def foo():
        print()
        
    print(foo)
    print(foo.__dict__)
    print(foo.__call__)  # 有输出
    #--------------------------------------------
    <function foo at 0x000002223464C488>
    {}
    <method-wrapper '__call__' of function object at 0x000002223464C488>
    

    函数即对象,对象foo加上(),就是调用此函数对象的 _call_() 方法

    # 2.如果一个对象要被调用 a() ,就需要__call__方法;
    class A:
        def __init__(self):
            print('init')
        def __call__(self,*args,**kwargs):
            print('call')
            # 没有返回值,函数为 None;
    print(A())  #实例
    print('-'*60)
    a = A()
    print(a())  #  # 实例对象 当函数(方法)用;
    #---------------------------------------------------------
    init
    <__main__.A object at 0x00000222369E3518>
    ------------------------------------------------------------
    init
    call
    None
    
    

    可调用对象——可调用实例(类)

    方法 意义
    _call_ 类中定义一个该方法,实例就可以像函数一样调用

    可调用对象:定义一个类,并实例化得到其实例,将实例像函数一样调用;

    class A:
        def __init__(self):
            print('init')
        def __call__(self,*args,**kwargs):
            print('call')
            print(args)
            print(kwargs)
            # 没有返回值,函数为 None;
    print(A())
    print('-'*60)
    a = A()
    print(a(1,22,33,a=100,b=200))
    print('-'*60)
    print(callable(a))
    #---------------------------------------------------------
    init
    <__main__.A object at 0x00000222369D8438>
    ------------------------------------------------------------
    init
    call
    (1, 22, 33)
    {'a': 100, 'b': 200}
    None
    ------------------------------------------------------------
    True
    
    

    类是可调用对象,那么我们就可以在类中动态的增加属性;

    练习:
    定义一个带缓存的fb序列的类,计算第N项目;

    class Fib:
        def __init__(self):
            # 使用列表缓存数据;
            self.items = [0,1,1]
            
        def __call__(self,index):
            if index >= len(self.items):
                for i in range(3,index+1):
                    self.items.append(self.items[i-1]+self.items[i-2])
            return self.items[index]   # 支持索引
        
        def __getitem__(self,index):  # 不同的获取方式2
            return self(index)
        
    fib = Fib()
    print(fib[20])
    print(fib(10))
    #---------------------------------------------------
    6765
    55
    
    # 魔术方法的使用 + 缓存,不用重复计算;
    class Fib:
        def __init__(self):
            # 使用列表缓存数据;
            self.items = [0,1,1]
            
        def __call__(self,index):
            if index >= len(self.items):
                for i in range(len(self),index+1):
                    self.items.append(self.items[i-1]+self.items[i-2])
            return self.items[index]
        
        def __getitem__(self,index):  # 不同的获取方式2
            return self(index)
        
        def __len__(self):  # 长度
            return len(self.items) 
        
        def __iter__(self):  # 迭代
            return iter(self.items)
        
    fib = Fib()
    print(fib[10])
    print(fib(10))
    
    for x in fib:  # 迭代 实例对象,不是函数;
        print(x)
    #----------------------------------------------------------
    55
    55
    0
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55

    相关文章

      网友评论

          本文标题:31.2-魔术方法—可调用对象

          本文链接:https://www.haomeiwen.com/subject/zdiroctx.html