首页 > 解决方案 > Python函数不更新属性

问题描述

我正在编写一个名为“Message”的类,它在其构造函数中采用字符串“message”。它基本上使用一些算法对消息进行编码和解码。非常基础和初学者的东西。课程如下:(这是一个很长的课程。)

class Message:
def __init__(self, message: str) -> None:
    self.message: str = message.strip()
    self.__displacement: int = 0
    self.__info: dict[Any, Any] = {
        "Encoded": False, "Algorithms": (), "Caesar_shift": "NONE"}

def __str__(self) -> str:
    return self.message

def __repr__(self) -> str:
    return self.message

_enc_types: list[str] = ["None", "CAESAR", "MORSE"]

_enc_funcs: dict[str, Any] = {
    "CAESAR": lambda message, *args: Message(message)._caesar_encode(*args),
    "MORSE": lambda message: Message(message)._morse_encode()
}

_dec_funcs: dict[str, Any] = {
    "CAESAR": lambda message: Message(message)._caesar_decode(),
    "MORSE": lambda message: Message(message)._morse_decode()
}

@staticmethod
def __modify_val(value: int, shift: str, mag: int) -> int:
    if shift == "LEFT":
        value -= mag
        if value < 0:
            value += 27
    elif shift == "RIGHT":
        value += mag
        if value > 26:
            value -= 27
    else:
        raise ValueError(
            f"Argument '{shift}' for parameter 'shift' is not allowed.")

    return value

def __displace(self, shift: str, mag: int) -> None:
    if shift.upper() == "RIGHT":
        self.__displacement += mag
    else:
        self.__displacement -= mag

    eval_dict: dict[bool, str] = {
        True: "LEFT",
        False: "RIGHT"
    }

    if self.__displacement != 0:
        self.__info["Caesar_shift"] = eval_dict.get(
            (self.__displacement < 0), "NONE")

def _caesar_encode(self, shift: str, mag: int) -> str:
    mag -= 1

    with open("F:\Practice_Python\jsons\caesar.json", "r") as file:
        dict_list = json.load(file)
        letter_dict: dict[str, int] = dict_list[0]
        num_dict: dict[str, str] = dict_list[1]

    self.message = ''.join([num_dict.get(str(self.__modify_val(letter_dict.get(
        letter, -1), shift, mag)), "?") for letter in self.message.lower()])

    self.__displace(shift, mag)
    return self.message

def _caesar_decode(self) -> None:
    if (not self.__info["Encoded"]) and (self.__info["Algorithms"][-1] != "Caesar"):
        raise EncodingError(
            "Given message is not encoded by allowed algorithms.")
    shift: str = self.__info["Caesar_shift"]
    mag: int = self.__displacement + 1

    if shift == "RIGHT":
        shift = "LEFT"
        self._caesar_encode(shift, mag)
        self.__displace(shift, mag)
    elif shift == "LEFT":
        shift = "RIGHT"
        self._caesar_encode(shift, mag)
        self.__displace(shift, mag)
    else:
        raise EncodingError(
            "Given message is not encoded by allowed algorithms.")

def _morse_encode(self) -> None:
    with open("F:\Practice_Python\jsons\morse.json", "r") as file:
        dict_morse: dict[str, str] = json.load(file)

    self.message = "".join(
        [dict_morse.get(char, char) + '   ' for char in self.message.lower()])

def _morse_decode(self) -> None:
    with open('F:\Practice_Python\jsons\morse.json', 'r') as file:
        dict_morse: dict[str, str] = json.load(file)
        dict_decode: dict[str, str] = {
            value: key for key, value in dict_morse.items()}

    self.message = ''

    for sub1 in self.message.lower().split('       '):
        for sub2 in sub1.split('   '):
            self.message += dict_decode.get(sub2, '?')
        self.message += ' '

def __update_encoded(self, type: str) -> None:
    self.__info["Encoded"] = True

    self.__info["Algorithms"] = list(self.__info["Algorithms"])
    self.__info["Algorithms"].append(type)
    self.__info["Algorithms"] = tuple(self.__info["Algorithms"])

def __update_decoded(self) -> None:
    self.__info["Algorithms"] = list(self.__info["Algorithms"])
    del self.__info["Algorithms"][-1]
    self.__info["Algorithms"] = tuple(self.__info["Algorithms"])

    if len(self.__info["Algorithms"]) == 0:
        self.__info["Encoded"] = False

def encode(self, type: str, *args):

    type = type.upper().strip()

    if type not in self._enc_types:
        raise EncodingError(
            "Given algorithm for encoding message is not present.")
    self._enc_funcs.get(type, type)(self.message, *args)

    self.__update_encoded(type)

def decode(self):
    type: str = self.__info["Algorithms"][-1]

    self._dec_funcs.get(type, type)()

    self.__update_decoded(type)

如果写得不好,请见谅。但是调用时的编码函数行为不正常。预期的:

>>> message = Message('Hello')
>>> message.encode('CAESAR', 'RIGHT', 4)
>>> print(message)
khoor

实际的:

>>> message = Message('Hello')
>>> message.encode('CAESAR', 'RIGHT', 4)
>>> print(message)
Hello

因此,它不会将属性更改为所需的值。但是该功能可以正确执行。这可能是编码功能的错。我找不到问题。请帮助和指导我。谢谢你。再次为凌乱的代码感到抱歉。

标签: pythonfunctionattributes

解决方案


_enc_funcs: dict[str, Any] = {
    "CAESAR": lambda message, *args: Message(message)._caesar_encode(*args),
    "MORSE": lambda message: Message(message)._morse_encode()
}

这些 lambda 函数创建一个的Message 对象(然后被丢弃);它们不对当前的 Message 对象进行编码。


推荐阅读