• 【Python】魔法方法之__call__,将对象当方法使用


    1、问题

    我刚开始接触爬虫的时候,只是看完了 python 的基础,对 python 的语法还没有一个很深入的了解,在使用 bs4 这个库的时候,对其中某些语法感到非常的惊奇,不明白是怎么实现的。

    bs4 的官方文档中说到:find_all() 几乎是 Beautiful Soup 中最常用的搜索方法,所以我们定义了它的简写方法。BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的:

    soup.find_all("a")
    soup("a")

    这里,soup 是一个 BeautifulSoup 对象,soup("a") 这很明显是把对象当方法使用了,这是怎么做到的呢?

    2、实现

    在 Python 中,除了用户定义的函数,调用运算符(即 ())还可以应用到其他对象上。内置的 callable() 函数用来判断一个对象能否调用。就是说,任何 Python 对象都可以表现得像函数一样,为此,只需实现实例方法 __call__

    来看一个简单的示例:

    class Sum:
        def __init__(self, x, y):
            self._x = x
            self._y = y

        def add(self):
            return self._x + self._y

        def __call__(self):
            return self.add()


    sum = Sum(12)

    print(sum.add())
    print(sum())
    print(callable(sum))

    输出:

    3
    3
    True

    这样就明白了,bs4 中亦是如此,源码如下:

    class Tag(PageElement):
        def __call__(self, *args, **kwargs):
            return self.find_all(*args, **kwargs)

    这背后涉及到的概念叫做可调用对象,Python 数据模型文档列出了 7 种可调用对象。

    • 用户定义的函数:使用 def 语句或 lambda 表达式创建。
    • 内置函数:使用 C 语言(CPython)实现的函数,如 len 或 time.strftime。
    • 内置方法:使用 C 语言实现的方法,如 dict.get。
    • 方法:在类的定义体中定义的函数。
    • :调用类时会运行类的 __new__ 方法创建一个实例,然后运行 __init__ 方法,初始化实例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调用函数。(通常,调用类会创建那个类的实例,不过覆盖 __new__ 方法的话,也可能出现其他行为。)
    • 类的实例:如果类定义了 __call__ 方法,那么它的实例可以作为函数调用。
    • 生成器函数:使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象。
  • 相关阅读:
    Oracle SQL FAQ
    miniasp(no encode)
    请看用javascript设置和读取cookie的简单例子
    asp流下载(Stream)
    (企业公司)网站开发方案
    asp发消息并代多个附件上传(多对多关系)
    tabpage1
    crystal report (asp调用水晶报表实例)
    上海万千文化传播有限公司(网站项目策划书)
    访问和更新Cookies集合
  • 原文地址:https://www.cnblogs.com/gl1573/p/10774182.html
Copyright © 2020-2023  润新知