【问题标题】:use str.format() witch class in python在 python 中使用 str.format() 女巫类
【发布时间】:2019-12-02 12:30:13
【问题描述】:

我有一个带有__getitem__() 函数的类,它可以像字典一样订阅。但是,当我尝试将其传递给str.format() 时,我得到了TypeError。如何在 python 中使用 format() 函数的类?

>>> class C(object):
      id=int()
      name=str()

      def __init__(self, id, name):
        self.id=id
        self.name=name

      def __getitem__(self, key):
        return getattr(self, key)

>>> d=dict(id=1, name='xyz')
>>> c=C(id=1, name='xyz')
>>>
>>> #Subscription works for both objects
>>> print(d['id'])
1
>>> print(c['id'])
1
>>>
>>> s='{id} {name}'
>>> #format() only works on dict()
>>> print(s.format(**d))
1 xyz
>>> print(s.format(**c))
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    print(s.format(**c))
TypeError: format() argument after ** must be a mapping, not C

【问题讨论】:

  • 看来你的问题不在于format(),而在于**
  • 但是我删除它并去print(s.format(c)) 它会引发 KeyError
  • c.__dict__ 会给你内部字典。但我建议添加一些属性来返回它,而不是直接返回它。你也可以让C继承自dict,而不是object
  • 是的,使用print(s.format(**c.__dict__)) 可以解决问题。谢谢

标签: python python-3.x string mapping typeerror


【解决方案1】:

正如一些 cmets 提到的你可以从 dict 继承,它不起作用的原因是:

如果语法 **expression 出现在函数调用中,则表达式必须计算为一个映射,其内容被视为附加关键字参数。如果关键字同时出现在表达式中并作为显式关键字参数出现,则会引发 TypeError 异常。

要使其工作,您需要实施 Mapping ABC。类似这样的东西:

from collections.abc import Mapping


class C(Mapping):

    id=int()
    name=str()

    def __init__(self, id, name):
        self.id = id
        self.name = name

    def __iter__(self):
        for x in self.__dict__.keys():
            yield x

    def __len__(self):
        return len(self.__dict__)

    def __getitem__(self, key):
        return self.__dict__[key]

这样你应该只能使用s = '{id}{name}'.format(**c) 而不是s = '{id}{name}'.format(**c.__dict__)

如果您希望能够像在字典中一样更改类变量,也可以使用 collections.abc 模块中的 MutableMapping。 MutableMapping 还需要实现__setitem____delitem__

【讨论】:

    猜你喜欢
    • 2019-04-03
    • 2022-08-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-27
    • 2020-01-17
    相关资源
    最近更新 更多