【问题标题】:How do we get a dictionary from classes,我们如何从类中获取字典,
【发布时间】:2019-01-02 22:35:09
【问题描述】:

这段代码没有按照我的意愿运行:

class A():        
    def __init__(self,b,c):

        self.b = 1
        self.c = 2

def get_dict(self):

    mydict={}        
    for att in A():
        mydict[att]=self.att
    return mydict

print(get_dict(s))

【问题讨论】:

标签: python function class dictionary


【解决方案1】:

你的意思是:

class A():        
    def __init__(self):

        self.b = 1
        self.c = 2

def get_dict(self):

    mydict={}        
    for att in [i for i in dir(A()) if not i.startswith('__')]:
        mydict[att]=getattr(self,att)
    return mydict

print(get_dict(A()))

输出:

{'b': 1, 'c': 2}

【讨论】:

  • 为什么参数self不是实例方法?
  • 如果每个实例有多个值怎么办?我们将如何运行代码
  • 你为什么要做dir(A()) 而不是获取你实际获得的对象的目录?这只是巧合地在这个例子中起作用(因为你碰巧传入了另一个A(),而A.__init__没有什么棘手的)。
  • @cricket_007 这个答案只是从 OP 的问题中复制了 API,所以我认为你问错人了。
【解决方案2】:

你可以只使用你班级的特殊属性__dict__:

class A():
    def __init__(self,b,c):

        self.b = 1
        self.c = 2

输出:

a = A(3,4)
print(a.__dict__)

{'b': 3, 'c': 4}

【讨论】:

  • 这不适用于属性、类属性、槽类、具有动态 dir/getattr 的类等。如果您首先要深入研究内部结构,不妨这样做没错。
【解决方案3】:

您可以使用__dict__ 属性来获取对象所有属性的字典。

class A():
    def __init__(self,b,c):

        self.b = b
        self.c = c

    def get_dict(self):
        return self.__dict__

print(A(1, 2).get_dict())

这个输出:

{'b': 1, 'c': 2}

【讨论】:

    【解决方案4】:

    这个问题有点含糊。

    如果您要求简单类实例的简单属性,这正是 vars 内置函数的用途:

    def get_dict(self):
        return vars(self)
    

    虽然我们正在这样做,但当您不编写方法时调用参数self 是很奇怪的;让我们称之为不同的东西:

    def get_dict(obj):
        return vars(obj)
    

    但有很多事情不会被采纳,包括:

    • 属性。
    • __slots__ 类的任何属性。
    • 类属性。
    • 来自__getattr__/__getattribute__ 和__dir__ 的动态属性。

    如果您想要尽可能多的这些,这就是 dir 内置函数的用途。但是dir 只是返回一个名称列表;然后你必须查看每个:

    def get_dict(obj):
        return {name: getattr(obj, name) for name in dir(obj)}
    

    这非常接近“每个whatever 我都可以使用obj.whatever”。


    但这可能比你想要的更多。它将包括私有成员、绑定方法以及 Python 解释器使用的特殊内容。您必须准确决定要过滤掉什么,但是一旦有了规则,它应该很容易实现。例如:

    def get_dict(obj):
        public = ((name, getattr(obj, name)) for name in dir(obj) if not name.startswith('_'))
        noncallablepublic = {name: value for name, value in everything if not callable(value)}
        return noncallablepublic
    

    如果你想要更高级,请查看inspect 模块,它具有用于此类过滤的辅助函数。


    虽然我们这样做了,但如果您有充分的理由对某些特定的类集执行此操作,您可能希望将这些类设计为更容易转换为 dict,并能够自定义它们的方式'被转换。

    例如,如果您使用 @dataclass 或第三方 attrs 库构建您的类,后者更强大且不需要 Python 3.7,这很简单:

    >>> @dataclasses.dataclass
    ... class A:
    ...     b: int = 1
    ...     c: int = 2
    >>> a = A()
    >>> a
    A(b=1, c=2)
    >>> print(dataclasses.asdict(a))
    {'b': 1, 'c': 2}
    

    dataclasses 库为我构建了__init__ 方法,还有__repr__ 方法,以及支持asdict 之类的其他东西,所以我根本不需要写任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多