Python AttributeError求助:'str'对象无'get_message_text'属性
问题概述
尝试用Message类实现凯撒密码时,运行代码触发AttributeError,报错行是original = self.get_message_text(),错误提示'str' object has no attribute 'get_message_text'。
完整报错信息
Traceback (most recent call last):
File ~.spyder-py3\ps5.py:239 in
print(Message.apply_shift('tweLve',12))
File ~.spyder-py3\ps5.py:129 in apply_shift
original = self.get_message_text()
AttributeError: 'str' object has no attribute 'get_message_text'
完整代码
import string class Message(object): def __init__(self, text): self.message_text = text #self.valid_words = load_words(WORDLIST_FILENAME) - commented out bc irrelevant here def get_message_text(self): ''' Used to safely access self.message_text outside of the class Returns: self.message_text ''' return self.message_text def build_shift_dict(self, shift): letters_lower, letters_upper = string.ascii_lowercase, string.ascii_uppercase new_dict={} for letter in letters_upper: new_dict[letter] = letters_upper[(letters_upper.index(letter) + shift) % 26] for letter in letters_lower: new_dict[letter] = letters_lower[(letters_lower.index(letter) + shift) % 26] return new_dict def apply_shift(self, shift): original = self.get_message_text() new = '' for letter in original: new += (self.build_shift_dict(shift)) #print(new) - a test print return new print(Message.apply_shift('tweLve',12))
问题原因及修复方案
核心错误:实例方法调用方式不对
你直接用类Message调用了apply_shift方法,而不是先创建类的实例。Python中,实例方法的第一个参数self默认指向类实例,如果你直接用类调用,这个self会被你传入的字符串'tweLve'替代,导致self变成了字符串对象,自然没有get_message_text这个方法。
两步修复:
修正调用方式:先创建
Message的实例,再调用apply_shift:msg = Message('tweLve') print(msg.apply_shift(12))修复
apply_shift的逻辑错误:原代码里new += (self.build_shift_dict(shift))会把整个字典拼到字符串里,完全错误。应该根据每个字母从移位字典中取对应字符,非字母保持原样:def apply_shift(self, shift): original = self.get_message_text() shift_dict = self.build_shift_dict(shift) # 提前生成字典,避免循环里重复创建 new = '' for letter in original: new += shift_dict.get(letter, letter) return new
修复后的完整代码
import string class Message(object): def __init__(self, text): self.message_text = text #self.valid_words = load_words(WORDLIST_FILENAME) - commented out bc irrelevant here def get_message_text(self): ''' Used to safely access self.message_text outside of the class Returns: self.message_text ''' return self.message_text def build_shift_dict(self, shift): letters_lower, letters_upper = string.ascii_lowercase, string.ascii_uppercase new_dict = {} for letter in letters_upper: new_dict[letter] = letters_upper[(letters_upper.index(letter) + shift) % 26] for letter in letters_lower: new_dict[letter] = letters_lower[(letters_lower.index(letter) + shift) % 26] return new_dict def apply_shift(self, shift): original = self.get_message_text() shift_dict = self.build_shift_dict(shift) new = '' for letter in original: new += shift_dict.get(letter, letter) return new # 正确调用 msg = Message('tweLve') print(msg.apply_shift(12))
内容的提问来源于stack exchange,提问作者BergholtStuttley

