用 python 实现一个只读的,只能有固定字段的类似结构体的特殊字典
本帖最后由 thepoy 于 2021-4-8 10:57 编辑昨天在写 metaWeblog 的时候,因为请求是固定的几个字段,但 python 中好像并没有 struct 以供使用,于是便想着简单实现一下:
```python
class BaseStruct(dict):
fields: Optional] = None
def __new__(cls, *args, **kwargs):
if not (isinstance(cls.fields, tuple) or isinstance(cls.fields, set)
or isinstance(cls.fields, list)):
raise AttributeError(
"`fields` is must be instance of tuple, set, or list")
if not set(args.keys()).issubset(set(cls.fields)):
raise OverflowError(
f"all keys of the dict object should be contained in `fields`: {cls.fields}"
)
return super().__new__(cls, *args, **kwargs)
def __getattr__(self, item: str):
if item not in self.fields:
raise KeyError("the key `%s` not exists" % item)
return self
def __setattr__(self, key, value):
raise NotImplementedError('read only')
def __setitem__(self, k, v):
raise NotImplementedError('read only')
```
基类写完,下面试一下好不好用:
```python
class BlogInfo(BaseStruct):
fields = ["blogid", "url", "blogName", "username", "password"]
rbi = {"blogid": 1, "url": "http", "blogName": "blog"}
bi = BlogInfo(rbi)
bi
# {'blogid': 1, 'url': 'http', 'blogName': 'blog'}
bi.url
# http
bi.url = "ftp"
# NotImplementedError: read only
bi["url"] = "ftp"
# NotImplementedError: read only
rbi = {"blogid": 1, "url": "http", "blogName": "blog", "content": "It is content"}
bi = BlogInfo(rbi)
# OverflowError: all keys of the dict object should be contained in `fields`: ['blogid', 'url', 'blogName', 'username', 'password']
rbi = {"blogid": 1, "url": "http"}# 能使用部分字段是与 namedtuple 的区别
bi = BlogInfo(rbi)
bi
# {"blogid": 1, "url": "http"}
```
好像可以用了。
学习学习,谢谢楼主分享心得! collections.namedtuple? 本帖最后由 thepoy 于 2021-4-8 10:54 编辑
santus36 发表于 2021-4-8 10:46
collections.namedtuple?
我之前用namedtuple,但它不能被xmlrpc序列化,而且所有字段都不能为空,就给换了。
fields里定义的是所有有效字段,但字典不需要包含全部字段。
页:
[1]