求助排查Python中NameError: name 'DEFAULT_STRING' is not defined错误
解决NameError: name 'DEFAULT_STRING' is not defined的问题
嘿,我看到你遇到的这个NameError了,问题出在类方法默认参数的作用域上,咱们一步步来拆解和修复:
错误原因
在定义__init__方法的默认参数时,你写了:
def __init__(self, string1 = DEFAULT_STRING, string2 = DEFAULT_STRING, string3 = DEFAULT_STRING):
这里的DEFAULT_STRING是你在TripleString类里定义的类常量,但Python在解析函数的默认参数值时,是在类定义的外部作用域查找这个名称的,而不是类的内部作用域。这时候类还没完全创建完成,所以找不到DEFAULT_STRING这个名字,就抛出了NameError。
另外,你在__init__里写的self.DEFAULT_STRING也是个小问题——虽然实例可以访问类变量,但类常量更推荐用类名来引用(比如TripleString.DEFAULT_STRING),这样代码逻辑更清晰。
修复方案
我们可以把默认参数改成None,然后在__init__方法内部判断,如果参数是None,就使用类的DEFAULT_STRING常量。这样既避开了作用域的问题,也能正确使用类常量。
以下是修正后的完整代码:
class TripleString: # intended class constants MIN_LEN = 1 MAX_LEN = 50 DEFAULT_STRING = "(undefined)" # constructor method def __init__(self, string1=None, string2=None, string3=None): # 先给实例变量设置默认值 self.string1 = TripleString.DEFAULT_STRING self.string2 = TripleString.DEFAULT_STRING self.string3 = TripleString.DEFAULT_STRING # 用setter方法设置传入的参数,若为None则保持默认值 if string1 is not None: self.set_string1(string1) if string2 is not None: self.set_string2(string2) if string3 is not None: self.set_string3(string3) # mutator ("set") methods def set_string1(self, string1): if self.valid_string(string1): self.string1 = string1 return True return False def set_string2(self, string2): if self.valid_string(string2): self.string2 = string2 return True return False def set_string3(self, string3): if self.valid_string(string3): self.string3 = string3 return True return False # accessor ("get") methods def get_string1(self): return self.string1 def get_string2(self): return self.string2 def get_string3(self): return self.string3 def to_string(self): return self.string1 + ", " + self.string2 + ", " + self.string3 # helper methods for entire class def valid_string(self, the_str): if len(the_str) >= TripleString.MIN_LEN and len(the_str) <= TripleString.MAX_LEN: return True return False # ------------- CLIENT -------------------------------------------------- # Create 4 TripleString objects and printing triple_string_num_1 = TripleString() print(triple_string_num_1.to_string()) triple_string_num_2 = TripleString("Alice") print(triple_string_num_2.to_string()) triple_string_num_3 = TripleString("Bob", "Chris") print(triple_string_num_3.to_string()) triple_string_num_4 = TripleString("Oliver", "Laurel", "Thea") print(triple_string_num_4.to_string()) print("") # mutating values using setter methods triple_string_num_1.set_string1("Lance") triple_string_num_2.set_string2("XYZ") triple_string_num_3.set_string1("Bobby") triple_string_num_4.set_string2("Felicity") print(triple_string_num_1.to_string()) print(triple_string_num_2.to_string()) print(triple_string_num_3.to_string()) print(triple_string_num_4.to_string()) print("") # testing if validation working properly if triple_string_num_4.set_string2(""): print("successful in setting empty string for string2 of 4th object," + \ "validation is not working properly") else: print( "failed in setting empty string for string2 of 4th object," + \ "validation is working properly") print("Value after setting: ", triple_string_num_4.get_string2())
关键修改点
- 修改__init__的默认参数:把
DEFAULT_STRING换成None,避免在类定义完成前引用类常量。 - 在__init__内部处理默认值:如果传入的参数是
None,就保持实例变量的默认值(类的DEFAULT_STRING);否则调用setter方法设置。 - 规范类常量的引用:把
self.MIN_LEN、self.MAX_LEN改成TripleString.MIN_LEN、TripleString.MAX_LEN,明确这是类级别的常量,增强代码可读性。
现在运行这段代码,应该就不会再出现NameError了,而且所有的功能(默认值、setter验证)都能正常工作。
内容的提问来源于stack exchange,提问作者PY__NEW_BEE
相关产品推荐
相关产品推荐

