【问题标题】:How to convert dict to class attributes in Python如何在 Python 中将 dict 转换为类属性
【发布时间】:2022-01-03 11:56:34
【问题描述】:

我们将完全采用 OOPS 方法将数据存储为类属性并根据需要调用定义的 get 方法,而不是使用 dict 来存储和传递数据。

在 Java 中我能够做到这一点,但在 Python 中遇到了一些麻烦。任何解决方案都会有所帮助。

import json

class InputModel:
    def __init__(self, input_payload):
        self.id1 = input_payload["id1"]
        self.route = RouteModel(input_payload["route"])
        self.id2 = input_payload["id2"]
        self.id3 = input_payload["id3"]
        self.id4 = input_payload["id4"]
        self.id5 = input_payload["id5"]

        def get_id1(self):
            return self.id1

        #similar for other ids


class RouteModel:
    def __init__(self, input_payload_route):
        self.id6 = input_payload_route["id6"]
        self.id7 = input_payload_route["id7"]
       
        def get_id6(self):
            return self.id6

        #similar for other ids
        
        

json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)
print(im.get_id1())
print(im.get_id6())

无法访问嵌套类属性

【问题讨论】:

  • 你可能想看看dataclassesim.get_id1() 在这里不起作用的原因是因为您的方法缩进了一层太深。我还应该提到 Python 不是 Java。不鼓励 Getter 和 Setter,因为您可以简单地使用 im.id1 等。如果您要访问嵌套实例的属性,您可以使用 im.route.id6

标签: python oop


【解决方案1】:

似乎您在类方法中额外缩进了 1 个,因此您无法访问它们。

另外,要到达 RouteModel 的 id6,您必须先参考“路线”:

import json

class InputModel:
    def __init__(self, input_payload):
        self.id1 = input_payload["id1"]
        self.route = RouteModel(input_payload["route"])
        self.id2 = input_payload["id2"]
        self.id3 = input_payload["id3"]
        self.id4 = input_payload["id4"]
        self.id5 = input_payload["id5"]

    def get_id1(self):
        return self.id1

        #similar for other ids


class RouteModel:
    def __init__(self, input_payload_route):
        self.id6 = input_payload_route["id6"]
        self.id7 = input_payload_route["id7"]
    
    def get_id6(self):
        return self.id6

        #similar for other ids
        
        

json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)
print(im.get_id1())
print(im.route.get_id6())

输出:

string
string

【讨论】:

  • 不使用路由可以调用get_id6()吗?
  • 您可以通过定义 'class InputModel(RouteModel):' 从 RouteModel 继承,然后您的 InputModel 实例可以设置为 id6,您也可以直接调用 get_id6 :im = InputModel(json_dict ) print(im.get_id1()) im.id6 = 'string' print(im.get_id6())
【解决方案2】:

问题是您只在本地范围内定义get_id*,如果您坚持在__init__ 方法中定义它,则需要将其分配给实例。

我最小化了您的代码示例以隔离您的问题。

class RouteModel:
    def __init__(self):
        self.id6 = "foo"

        def get_id6(self_=self):
            return self_.id6

        self.get_id6 = get_id6

rm = RouteModel()
print(rm.get_id6())

>>> "foo"

【讨论】:

  • 所以基本上我创建的可以称为实例变量而不是类变量对吗?我应该在 init 之外定义变量?
  • 你是对的,检查我的旧答案here 我尝试总结术语的地方
【解决方案3】:

如果我正确理解您的问题,您希望能够直接将 id 作为属性访问,无论它们在字典中嵌套多深。
此解决方案递归地创建属性:

import json

class InputModel:
    def __init__(self, payload):
        self.create_attrs(payload)

    def create_attrs(self, d):
        for key, value in d.items():
            # if the value is a dict, call create_attrs recursively
            if isinstance(value, dict):
                self.create_attrs(value)
            else:
                # create an attribute key=value, e.g. id1="string"
                setattr(self, key, value)


json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)

print(im.id1)
print(im.id6)

【讨论】:

    【解决方案4】:

    在查看提供的答案后,大多数都定义了实例属性而不是类属性。

    如果我在这里错了,请纠正我,但我认为这是定义类属性的方式对吗?

    import json
    
    class InputModel:
        def __init__(self, input_payload):
            InputModel.id1 = input_payload["id1"]
            InputModel.route = RouteModel(input_payload["route"])
            InputModel.id2 = input_payload["id2"]
            InputModel.id3 = input_payload["id3"]
            InputModel.id4 = input_payload["id4"]
            InputModel.id5 = input_payload["id5"]
    
            def get_id1():
                return InputModel.id1
            #OR
            #@classmethod
            #def get_id1(cls):
            #    return cls.id1
    
            #similar for other ids
    
    
    class RouteModel:
        def __init__(self, input_payload_route):
            RouteModel.id6 = input_payload_route["id6"]
            RouteModel.id7 = input_payload_route["id7"]
           
            def get_id6():
                return RouteModel.id6
    
            #similar for other ids
            
            
    
    json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
    json_dict = json.loads(json_str)
    
    InputModel(json_dict)
    print(InputModel.get_id1())
    print(InputModel.route.get_id6())
    print(RouteModel.get_id6())
    

    【讨论】:

      猜你喜欢
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      相关资源
      最近更新 更多