【问题标题】:Does setattr / getattr / self.__dict__ accept attribute names that would normally be disallowed?setattr / getattr / self.__dict__ 是否接受通常不允许的属性名称?
【发布时间】:2019-07-06 17:11:46
【问题描述】:

我注意到虽然这不起作用:

class MyClass:
    def __init__(self, i):
        self.5i = i

myobj = MyClass(5)

print(myobj.5i)

这确实有效:

class MyClass:
    def __init__(self, i):
        setattr(self, '5i', i)

myobj = MyClass(5)

print(getattr(myobj, '5i'))

更重要的是,这也有效:

class MyClass:
    def __init__(self, i):
        self.__dict__['i.j'] = i

myobj = MyClass(5)

print(myobj.__dict__['i.j'])

sn-ps 2 和 3 是否可以保证工作?还是我们宁愿在这里有鼻恶魔,它们将无辜的灵魂带入地狱的邪恶计划是让这种恶作剧似乎奏效,而实际上却没有?

我问的原因是我正在将 JSON 对象(从 API 接收)转换为类。而且由于服务器喜欢返回有时看起来很重要的额外的未记录字段,而且我不喜欢丢失数据......这就是目前大多数 JSON 到对象的转换归结为:

class FooResponse:
    def __init__(self, json_string):
        self.__dict__.update(json.loads(json_string))

但是,但是……如果服务器返回一个带有一些非常奇怪的字段的 JSON 怎么办,例如:

{
    "foo.bar": "Fizz-Buzz",
    "1337": "speek"
}

或者诸如此类的?我必须尽我最大的努力来清理它还是简单的self.__dict__.update(json.loads(json_string)) 合适?

服务器文档接受 JSON 调用,其字段名称包含点或数字的字符串表示形式,因此我发现它也可能返回这样的 JSON。

【问题讨论】:

  • 相关,不一定重复:stackoverflow.com/questions/26534634/…
  • 您应该始终清理来自不受信任来源的输入。 xkcd.com/327
  • 嗯,这就是判断的地方:你信任谁?您的 API 是“信任”API,即您的用户了解所有信息,并且只为您提供良好的输入,还是您的 API 是“可疑的错误输入”API,即您的用户可能无知或恶意?一些 API 是混合的:例如,您可能有方法 set_trustedset_untrusted(可能有更好的名称)。只是您提到 JSON 和 JSON 经常(并非总是,但经常)来自不受信任的来源。

标签: python attributes


【解决方案1】:

__dict__ 属性只是一个普通的字典,所以是的,它允许普通字典允许的任何键,可以是任何可散列的对象。但是,这并不意味着 self.__dict__.update(json.loads(json_string)) 是正确的做法,因为您不仅无法使用简单的点运算符访问异常命名的键,而且还会引入意外行为甚至安全风险,因为 JSON 对象,其内容通常来自外部,现在可以覆盖对象的任何属性,包括内部属性,例如 __dict__ 本身。您应该坚持将json.loads(json_string) 分配给对象的常规属性。

【讨论】:

  • “您应该坚持将 json.loads(json_string) 分配给对象的常规属性。” - 那我为什么要提供类和模型而不是简单地返回(嵌套)字典?
  • 详细说明:foo.returnedAttributes['bar'].returnedAttributes['baz'].returnedAttributes['fizz'] 是......令人生畏。我的重点是当 API 文档返回字段包含“bar”的 JSON 对象并映射到字段包含“baz”的对象并映射到字段包含“fizz”的对象时启用像 foo.bar.baz.fizz 这样的访问...
  • 如果这是课程的唯一目的,那么是的,你不应该一开始就提供这个课程。使用常规变量来存储 JSON 对象就足够了。
  • 该类还提供了许多方便的方法。
  • 我已经在回答您的问题时概述了您的方法的潜在缺点。将 JSON dict 转换为类属性的便利是否值得缺点完全取决于您根据您的实际使用情况来决定。
猜你喜欢
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多