python - 在 python 中使用 str.format() 女巫类
问题描述
我有一个具有__getitem__()
可订阅功能的类,就像字典一样。但是,当我尝试将它传递给 a 时,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
解决方案
正如一些评论提到你可以继承自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__)
如果您希望能够像在字典中一样更改类变量,也可以使用MutableMapping
from module。collections.abc
MutableMapping 还需要实现__setitem__
和__delitem__
推荐阅读
- flutter - 如何在所有页面中显示当前播放的视频,例如 udemy in flutter?
- reactjs - 使用 dockerised 前端和 dockerise 后端图像部署应用程序
- android - 在 .gradlew 命令行构建中找不到 dokka?
- time-complexity - 对于代码中的多个参数,O(M+N) 比 O(2N) 更正确的混淆
- c++ - 通过递归将两个数字相乘
- php - 如何在不使用内置函数的情况下反转 PHP 中的字符串?
- macos - 如何在 MacOS 上通过 ANGLE 使用集成显卡?
- c++ - 对作为数组给出的两个集合实现联合操作
- reactjs - componentDidUpdate 无法识别状态变化
- go - 如何更新 many2many 连接表中的自定义字段?