作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
假设我在 python 中有一个函数,它返回一个带有一些对象的字典。
class MyObj:
pass
def my_func():
o = MyObj()
return {'some string' : o, 'additional info': 'some other text'}
在某些时候,我注意到重命名键 'some string'
是有意义的,因为它具有误导性,并且不能很好地描述该键实际存储的内容。但是,如果我只是更改 key ,那么使用这段代码的人会非常恼火,因为我没有通过弃用期给他们时间来修改他们的代码。
所以我考虑实现弃用警告的方式是在 dict 周围使用薄包装:
from warnings import warn
class MyDict(dict):
def __getitem__(self, key):
if key == 'some string':
warn('Please use the new key: `some object` instead of `some string`')
return super().__getitem__(key)
这样我可以创建新旧键指向同一个对象的字典
class MyObj:
pass
def my_func():
o = MyObj()
return MyDict({'some string' : o, 'some object' : o, 'additional info': 'some other text'})
最佳答案
老实说,我不认为您的解决方案有什么特别错误或反模式,除了 my_func
必须复制每个已弃用的键及其替换项(见下文) .
您甚至可以稍微概括一下(以防您决定弃用其他键):
class MyDict(dict):
old_keys_to_new_keys = {'some string': 'some object'}
def __getitem__(self, key):
if key in self.old_keys_to_new_keys:
msg = 'Please use the new key: `{}` instead of `{}`'.format(self.old_keys_to_new_keys[key], key)
warn(msg)
return super().__getitem__(key)
class MyObj:
pass
def my_func():
o = MyObj()
return MyDict({'some string' : o, 'some object': o, 'additional info': 'some other text'})
然后
>> my_func()['some string'])
UserWarning: Please use the new key: `some object` instead of `some string`
为了“弃用”更多 key ,您现在要做的就是更新 old_keys_to_new_keys
。
my_func
如何必须复制每个已弃用的键及其替换键。这违反了 DRY 原则,并且在您确实需要弃用更多 key 时会使代码困惑(并且您必须记住同时更新
MyDict.old_keys_to_new_keys
和
my_func
)。如果我可以引用雷蒙德·赫廷格的话:
There must be a better way
可以通过对 __getitem__
进行以下更改来解决此问题:
def __getitem__(self, old_key):
if old_key in self.old_keys_to_new_keys:
new_key = self.old_keys_to_new_keys[old_key]
msg = 'Please use the new key: `{}` instead of `{}`'.format(new_key, old_key)
warn(msg)
self[old_key] = self[new_key] # be warned - this will cause infinite recursion if
# old_key == new_key but that should not really happen
# (unless you mess up old_keys_to_new_keys)
return super().__getitem__(old_key)
那么my_func
只能使用新的key:
def my_func():
o = MyObj()
return MyDict({'some object': o, 'additional info': 'some other text'})
行为是相同的,任何使用已弃用 key 的代码都会收到警告(当然,访问新 key 也可以):
print(my_func()['some string'])
# UserWarning: Please use the new key: `some object` instead of `some string`
# <__main__.MyObj object at 0x000002FBFF4D73C8>
print(my_func()['some object'])
# <__main__.MyObj object at 0x000002C36FCA2F28>
关于python - 如何弃用 dict 键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54095279/
我是一名优秀的程序员,十分优秀!