首页 > 编程问答 >使用Python时如何避免`setattr`(和`getattr`)?以及是否有必要避免

使用Python时如何避免`setattr`(和`getattr`)?以及是否有必要避免

时间:2024-08-01 05:46:07浏览次数:12  
标签:python protocol-buffers setattr

如果我想向协议缓冲区中的字段添加一个在编译时未知的值,我目前正在做 setattr 我通常不喜欢使用 setattr ,因为它看起来不太安全。但是当我知道该对象是 protobuf 时,我认为这很好,因为我设置它的值必须是 protobuf 允许的类型。所以也许它并不是真的不安全?

让我举例说明。 首先,假设我有这个 protobuf:

message Person {
  string first_name = 1;
  string second_name = 1;
  int age = 3;
}

然后我有一些使用上面的 protobuf 的代码:

from person_pb2 import Person

my_info = {"first_name": "Mike", "last_name": "example", "age": 999}
me = Person()
for field, value in my_info:
  setattr(me, field, value)

这是处理 protobuf 的一种非常灵活的方式。例如,我不能像在 dict 中那样指定它,说 me[field] = value 然而, me[field] = value 是绝对安全的。如果使用 setattr 时字段/属性的值类型错误,我会收到错误: TypeError: bad argument type for built-in operation

因此,我很想说,对于 protobufs,使用 setattr 完全没问题,并且,事实上,这确实是以编程方式向 protobuf 字段添加值的唯一方法。它是否正确?有更好或更安全的方法吗? 我不能做类似 me.first_name = "Mike" 的事情,因为我需要它是程序化的。


你问了关于在 Python 中使用 setattr 处理 protobuf 的问题,特别是关于它是否是处理它们的安全且首选方式。你对 setattr 的谨慎是值得赞赏的,因为它在处理不受信任的输入时确实会带来安全风险,但你说的对,在 protobuf 的上下文中,它通常是可以接受的。

为什么 setattr 在这里可以接受

  • 类型安全: Protobuf 强制执行严格的类型检查。如果你尝试使用错误类型的 setattr 设置字段,protobuf 库将在运行时引发错误。这减轻了与 setattr 相关的常见安全问题之一,即设置错误类型的属性。
  • 灵活性: 如你所述, setattr 在程序化地填充 protobuf 时提供了灵活性,尤其是在字段名称在运行时才知道的情况下。

代码示例

你的代码示例很好地展示了如何在 protobuf 的上下文中安全地使用 setattr

from person_pb2 import Person

my_info = {"first_name": "Mike", "last_name": "example", "age": 999}
me = Person()
for field, value in my_info.items():  # 使用 .items() 迭代字典
    setattr(me, field, value)

替代方案和最佳实践

尽管 setattr 在这种情况下可以接受,但请考虑以下替代方案和最佳实践:

  1. MessageToDict ParseDict Protobuf 库提供了 MessageToDict ParseDict 函数,这些函数允许你在字典和 protobuf 消息之间进行转换。如果你的数据最初是字典格式,则此方法可能更干净且更易于阅读。

```python from google.protobuf.json_format import MessageToDict, ParseDict

my_info = {"first_name": "Mike", "last_name": "example", "age": 999} me = ParseDict(my_info, Person()) ```

  1. HasField 进行条件设置: 如果你需要有条件地设置字段,请使用 HasField 方法来检查该字段是否已设置,尤其是在使用重复字段或可选字段时。

python if not me.HasField("first_name"): setattr(me, "first_name", "Mike")

  1. 验证: 始终验证来自不受信任来源的数据,即使在使用 protobuf 时也是如此。Protobuf 确保类型安全,但不一定确保数据有效性。

结论

简而言之,在处理 protobuf 时,在动态设置字段时, setattr 是一个可接受且经常使用的工具。只要你确信正在处理的数据是类型安全的,你就可以在代码中自信地使用它。但是,请探索 protobuf 库提供的替代方法,例如 MessageToDict ParseDict ,以获得更具可读性和 Python 风格的代码。

标签:python,protocol-buffers,setattr
From: 78817555

相关文章

  • Java sshtools 生成的 EDDSA 签名与 Python 的 pycryptome 生成的签名不匹配
    我有一个python库,它使用pycryptodomelibrary使用openssh格式的ED25519私钥使用Ed25519算法对数据进行签名。然后需要使用sshtools库和相应的公钥在Java应用程序中验证签名。但是签名验证失败。约束:从文件中读取私钥/公钥很重要。我无法......
  • Elastic python请求超时错误:池达到最大大小,不允许更多连接
    我正在使用Elasticsearchpython模块。我正在尝试像这样建立到服务器的连接es=Elasticsearch([config.endpoint],api_key=config.key,request_timeout=config.request_timeout)服务器连接,然后我尝试执行丰富策略。es.enr......
  • 使用 python 将 JSON 数据空值导入数据库。收到此错误 - 数据需要字符串或类似字节的
    我正在尝试使用python将JSON数据集导入到我的PostgreSQL数据库,但在尝试导入null值时会抛出错误。表的名称是Loan_info。我在python中尝试过此操作:-forfieldinloan_info:ifloan_info[field]in['Null','null',None]:......
  • Python 将脚本转换为 exe 并给出 PermissionError
    我有一个Python(Windows10)脚本,其功能之一是创建备份。这是函数:defcreate_backups(self,file:str,counter:int=None)->None:counter=counteror1res=self.re_obj.match(file)ifresisNoneorlen(res.groups())==0:back_file=......
  • conda update python 不会更新,但 conda update --all 会更新
    我正在尝试更新我的venv。这就是我看到的(base_test)>condaupdatepythonCollectingpackagemetadata(current_repodata.json):doneSolvingenvironment:done==>WARNING:Anewerversionofcondaexists.<==currentversion:4.10.3latestversion:24......
  • 如何使用 Selenium (python) 访问另一个影子根中影子根中的元素?
    我有以下代码和HTML结构(我不是这方面的专家)。我正在尝试抓取HTML代码末尾的96.00C元素,其路径是:Xpath://*[@id="_grid"]/set-class2/div2/text-binding//text()完整Xpath:/html/body/main/div/div3/div3/......
  • 在Python中,如何在一段时间内接受输入
    我正在尝试用Python制作一个蛇游戏,但不知道如何制作它,以便蛇在没有玩家输入的情况下继续移动,所以如果有人知道一个简单的方法来做到这一点,我需要在2秒后取消输入将不胜感激代码如下:importrandomimportsysplayerY=(1)playerX=(0)appleY=random.randint(1,10)appl......
  • 在Python中单步执行代码时是否可以引发异常
    当我在IDE(例如PyCharm)中单步执行代码时,我想转储函数的参数(以供以后使用,例如复制它)。计划的场景是在某处设置断点,然后引发异常(这不在我运行的代码中,这就是重点),并捕获它。代码应该如下所示:defexception_cathcher_decorator(func):try:returnfunc(*f_args,**f_k......
  • 解决python自动化操作异常处理的问题
    在python自动化领域,往往要用到pyautogui,pywin32等模块实现自动化操作。然而,这种自动化操作,本身具有一定的局限性,其中最主要的一个问题就是,一旦执行结果不按照脚本预设的来执行,往往会抛出异常,导致程序中断。解决这个问题,主要有这么几种思路:第一,每一次操作后分情况讨论。这种方......
  • Python爬虫入门03:用Urllib假装我们是浏览器
    文章目录引言Urllib库简介Request模块详解Error模块与异常处理Parse模块与URL解析Robotparser模块模拟浏览器请求使用Request方法添加请求头信息代码示例1.设置请求URL和请求头2.定义请求参数并转换为适当的格式3.使用Request方法封装请求4.发送请求并获取响应常用......