You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类Getter与Setter装饰器应用及代码优化咨询

问题解答

1. 类变量与实例变量的使用优化

你的类变量和实例变量使用逻辑基本通顺,但存在几个可以优化的点:

类变量的问题与调整

  • auth_bearer和headers不应设为类变量:类变量在类定义阶段就会初始化,后续如果修改BotLine.secret_token,auth_bearer不会自动更新(因为它是一次性计算的)。而且所有实例共享同一个headers对象,若某个实例修改headers会影响所有实例,存在状态污染风险。
  • 优化方案:将auth_bearer和headers改为动态计算的实例属性,用@property装饰器实现,确保每次获取时都是最新值:
class BotLine:
    secret_token = "secret_token_here"
    endpoint_url = "https://api.line.me/v2/bot/message/push"
    destination_id_test = "test_group_id"
    destination_id_real = "real_group_id"

    @property
    def auth_bearer(self):
        return f"Bearer {self.secret_token}"

    @property
    def headers(self):
        return {"Content-Type": "application/json", "Authorization": self.auth_bearer}

实例变量的精简

  • 移除冗余的实例变量:self.chat仅在__init__中设为None,后续未被使用;self.data每次调用set_chat_message都会重新生成,且send_to_chat直接用返回值,没必要存在实例中。优化后的__init__:
def __init__(self, test_mode="Y"):
    self._test_mode = test_mode  # 存储测试模式,方便后续切换

2. 使用GETTER/SETTER装饰器改造方法

Python的@property装饰器可实现getter,配合@<属性名>.setter实现setter,以下是针对性改造:

改造set_destination_id

将test_mode设为可修改的属性,destination_id作为只读属性动态计算,替代原set_destination_id方法:

class BotLine:
    # ... 其他类变量 ...

    def __init__(self, test_mode="Y"):
        self._test_mode = test_mode  # 下划线开头表示私有变量,约定外部直接修改

    @property
    def test_mode(self):
        return self._test_mode

    @test_mode.setter
    def test_mode(self, value):
        # 增加参数验证,确保输入合法
        if value not in ("Y", "N"):
            raise ValueError("test_mode必须为'Y'或'N'")
        self._test_mode = value

    @property
    def destination_id(self):
        return self.destination_id_real if self._test_mode == 'N' else self.destination_id_test

使用时,直接通过bot.destination_id获取目标ID,通过bot.test_mode = "N"切换环境,destination_id会自动更新。

改造set_chat_message

将消息内容设为可设置的属性,设置时自动生成消息结构,替代原set_chat_message方法:

class BotLine:
    # ... 其他代码 ...

    def __init__(self, test_mode="Y"):
        self._test_mode = test_mode
        self._chat_content = None

    @property
    def chat_content(self):
        return self._chat_content

    @chat_content.setter
    def chat_content(self, content):
        self._chat_content = content
        # 设置内容时自动生成消息数据
        self._message_data = {
            "to": self.destination_id,
            "messages": [
                {
                    "type": "text",
                    "text": f"$ {content} $",
                    "emojis": [
                        {"index": 0, "productId": "5ac2213e040ab15980c9b447", "emojiId": "001"}
                    ]
                },
                {"type": "sticker", "packageId": "6136", "stickerId": "10551377"}
            ]
        }

    @property
    def message_data(self):
        if not self._chat_content:
            raise ValueError("请先设置chat_content")
        return self._message_data

修改send_to_chat方法适配新逻辑:

def send_to_chat(self, chat=None):
    if chat:
        self.chat_content = chat
    response = requests.post(
        self.endpoint_url,
        data=json.dumps(self.message_data),
        headers=self.headers,
        verify=False
    )
    return json.loads(response.text)

完整优化后代码

import datetime
import json
import requests


class BotLine:
    secret_token = "secret_token_here"
    endpoint_url = "https://api.line.me/v2/bot/message/push"
    destination_id_test = "test_group_id"
    destination_id_real = "real_group_id"

    def __init__(self, test_mode="Y"):
        self._test_mode = test_mode
        self._chat_content = None

    @property
    def test_mode(self):
        return self._test_mode

    @test_mode.setter
    def test_mode(self, value):
        if value not in ("Y", "N"):
            raise ValueError("test_mode必须为'Y'或'N'")
        self._test_mode = value

    @property
    def destination_id(self):
        return self.destination_id_real if self._test_mode == 'N' else self.destination_id_test

    @property
    def auth_bearer(self):
        return f"Bearer {self.secret_token}"

    @property
    def headers(self):
        return {"Content-Type": "application/json", "Authorization": self.auth_bearer}

    @property
    def chat_content(self):
        return self._chat_content

    @chat_content.setter
    def chat_content(self, content):
        self._chat_content = content
        self._message_data = {
            "to": self.destination_id,
            "messages": [
                {
                    "type": "text",
                    "text": f"$ {content} $",
                    "emojis": [
                        {"index": 0, "productId": "5ac2213e040ab15980c9b447", "emojiId": "001"}
                    ]
                },
                {"type": "sticker", "packageId": "6136", "stickerId": "10551377"}
            ]
        }

    @property
    def message_data(self):
        if not self._chat_content:
            raise ValueError("请先设置chat_content")
        return self._message_data

    def send_to_chat(self, chat=None):
        if chat:
            self.chat_content = chat
        response = requests.post(
            self.endpoint_url,
            data=json.dumps(self.message_data),
            headers=self.headers,
            verify=False
        )
        return json.loads(response.text)


if __name__ == "__main__":
    chat_message = f"\N{Robot Face}: Testing - {datetime.datetime.now().strftime('%Y%m%d%H%M%S')}"
    bot = BotLine(test_mode="Y")
    response = bot.send_to_chat(chat=chat_message)
    print(f"{json.dumps(response, indent=2)}")

内容的提问来源于stack exchange,提问作者insignificant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:20:02