Python如何在同一类内部正确引用静态方法和静态属性?
错误原因
- 类定义阶段无法引用未创建完成的类:你在定义类属性
operation_functions时使用Calculator.add_number这类写法,此时Python还在解析Calculator类的结构,类对象还没有被完全创建,因此无法识别Calculator标识符,直接抛出未定义错误。 - 存在笔误:
calculate_numbers方法中引用的Calculator.operations和你实际定义的类属性名operation_functions不一致,即使解决了类未定义的问题,这里也会报属性不存在错误。
符合Python规范的实现方案
推荐两种常用的实现方式,均符合PEP8编码规范:
方案1:类定义完成后再赋值类属性
类完全创建完成后,就可以正常引用类内部的静态方法、属性,直接在类外给类属性赋值即可:
# 先定义Calculator类的所有方法 class Calculator: """计算器类""" @staticmethod def calculate_numbers(operation, *vals): """根据传入的操作类型调用对应的计算函数""" function = Calculator.operation_functions[operation] return function(*vals) @staticmethod def add_number(*vals): """执行加法运算并返回结果""" History.add_addition_calculation(*vals) return Calculator.get_last_result() @staticmethod def subtract_number(*vals): # 减法实现逻辑 pass @staticmethod def multiply_number(*vals): # 乘法实现逻辑 pass @staticmethod def divide_number(*vals): # 除法实现逻辑 pass @staticmethod def get_last_result(): # 获取最近计算结果的逻辑 pass # 类创建完成后再给运算函数字典赋值,此时可以正常引用Calculator的静态方法 Calculator.operation_functions = { "addition": Calculator.add_number, "subtraction": Calculator.subtract_number, "multiplication": Calculator.multiply_number, "division": Calculator.divide_number, }
方案2:用类方法初始化类属性
如果不希望把类属性的定义逻辑放在类外部,可以在类内部定义初始化类属性的类方法,类加载完成后调用一次即可:
class Calculator: """计算器类""" # 先声明类属性 operation_functions = None @classmethod def init_operation_map(cls): """初始化运算方法映射字典""" cls.operation_functions = { "addition": cls.add_number, "subtraction": cls.subtract_number, "multiplication": cls.multiply_number, "division": cls.divide_number, } @staticmethod def calculate_numbers(operation, *vals): """根据传入的操作类型调用对应的计算函数""" function = Calculator.operation_functions[operation] return function(*vals) # 其余静态方法实现和方案1一致,此处省略 @staticmethod def add_number(*vals): History.add_addition_calculation(*vals) return Calculator.get_last_result() @staticmethod def subtract_number(*vals): pass @staticmethod def multiply_number(*vals): pass @staticmethod def divide_number(*vals): pass @staticmethod def get_last_result(): pass # 类加载完成后调用一次初始化方法即可 Calculator.init_operation_map()
补充说明
在类已经创建完成的场景下,静态方法内部用类名.属性/方法名引用类的其他静态资源是完全符合规范的,仅在类还处于解析阶段的定义过程中不能这么操作。
内容的提问来源于stack exchange,提问作者Wizard
相关产品推荐
相关产品推荐

