【问题标题】:To call a function from a class, does Python iterate through every function the class has until it finds the function to call?要从类中调用函数,Python 是否会遍历该类的每个函数,直到找到要调用的函数?
【发布时间】:2020-06-02 18:31:03
【问题描述】:

例如,假设我有这个:

class RandomFunctions:
    def function_1:
        print('function 1 calling')

    def function_2:
        print('function_2 activated')

    def function_3:
        print('function_3 activated')

    def function_4:
        print('function_4 activated')

RandomFunctions().function_4()

要调用function_4,Python 是遍历类中的所有其他函数,检查它是否是正确的函数,还是直接调用它?

【问题讨论】:

    标签: python python-3.x function class


    【解决方案1】:

    function_4 是一个类属性,其名称存储在实现映射协议的对象中。查找是通过对该对象的直接索引来完成的。不涉及迭代,定义函数的顺序在很大程度上是无关紧要的。

    >>> type(RandomeFunctions.__dict__)
    <class 'mappingproxy'>
    >>> RandomFunctions.__dict__['function_4'] is RandomFunctions.function_4
    True
    

    【讨论】:

    • 有趣!尽管this 中的实验表明该函数在类中越靠前,执行所需的时间就越长。这怎么可能?
    • mappingproxy 类基本上只是 dict 的只读包装器,它会阻止您对其进行更新。访问一个或另一个元素所需时间的任何变化似乎是由于底层哈希表的行为,而不是其元素的任何直接迭代。
    【解决方案2】:

    我做了一个小实验,结果如下:

    from time import perf_counter
    
    class RandomFunctions: # Defines 20000 functions
        for n in range(20000):
            exec(f"""def function_{n}(self):
                print(f'function {n} calling')""")
    
    a = RandomFunctions()
    start = perf_counter()
    a.function_0() # Calls first function
    end = perf_counter()
    print(end-start)
    

    输出:

    function 0 calling
    0.03125423399999949
    

    #

    start = perf_counter()
    a.function_1999() # Calls the 1999th function
    end = perf_counter()
    print(end-start)
    

    输出:

    function 1999 calling
    0.0849990759999999
    

    这个实验的结论似乎是:

    该类确实会遍历函数以找到正确的函数。

    【讨论】:

    • 对于任何结论而言,这都是非常少的数据。
    • 我无法重现这些时间 - 两者的速度大致相同(0.000120.00011)。请注意,您的时间只是单个数据点,还包括 RandomFunctions 的实例化。考虑使用适当的基准测试工具,例如pyperftimeit。考虑从计时中删除RandomFunctions 实例化,或单独对实例化进行基准测试以从组合测试中减去它。
    猜你喜欢
    • 2019-08-22
    • 2017-05-01
    • 1970-01-01
    • 2021-06-18
    • 2018-03-19
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多