[英]How to replace has_key in python3?
我尝试安装Auto-SelfControl并在执行以下命令时卡住:
sudo /usr/bin/python auto-selfcontrol.py
它显示错误:
AttributeError:'dict'对象没有属性'has_key'
我正在寻找解决方案,最后以in运算符替换has_key ,但是由于我只了解python的基础知识,因此代码对我来说非常复杂。
在3个地方使用过has_key ,您可以帮我更改它以便可以在python3上运行吗?
1。
def check_if_running(username):
""" checks if self-control is already running. """
defaults = get_selfcontrol_settings(username)
return defaults.has_key("BlockStartedDate") and not NSDate.distantFuture().isEqualToDate_(defaults["BlockStartedDate"])
2-4。
def check_config(config):
""" checks whether the config file is correct """
if not config.has_key("username"):
exit_with_error("No username specified in config.")
if config["username"] not in get_osx_usernames():
exit_with_error(
"Username '{username}' unknown.\nPlease use your OSX username instead.\n" \
"If you have trouble finding it, just enter the command 'whoami'\n" \
"in your terminal.".format(
username=config["username"]))
if not config.has_key("selfcontrol-path"):
exit_with_error("The setting 'selfcontrol-path' is required and must point to the location of SelfControl.")
if not os.path.exists(config["selfcontrol-path"]):
exit_with_error(
"The setting 'selfcontrol-path' does not point to the correct location of SelfControl. " \
"Please make sure to use an absolute path and include the '.app' extension, " \
"e.g. /Applications/SelfControl.app")
if not config.has_key("block-schedules"):
exit_with_error("The setting 'block-schedules' is required.")
if len(config["block-schedules"]) == 0:
exit_with_error("You need at least one schedule in 'block-schedules'.")
if config.get("host-blacklist", None) is None:
print("WARNING:")
msg = "It is not recommended to directly use SelfControl's blacklist. Please use the 'host-blacklist' " \
"setting instead."
print(msg)
syslog.syslog(syslog.LOG_WARNING, msg)
尽管其他答案中的零散解决方案会起作用,但该方法存在缺陷,原因仅在于它容易犯小错误,错过需要修复的地方等。更好的解决方案是仅使用2to3
转换器 。 您可以一口气修复所有文件:
$ 2to3 -f has_key -w auto-selfcontrol.py
这只能运行的has_key
定影液从转换dict.has_key(key)
来key in dict
。 当然,您可以自己进行修复,但是在这种情况下,简单的程序化修复程序就可以正常工作。 您可能只想在不使用-f has_key
情况下运行它,以便在Py2和Py3之间应用任何其他重大更改的情况下,一次应用所有修复程序。
2to3
几乎可以自动处理所有事情,但Py2 str
类型更改(这是代码逻辑决定,即给定的str
文字应该是Py3中的bytes
还是str
)和整数除法(其中/
可能需要更改为//
,基于计算是逻辑上的浮点除法还是底数除法)。 但是对于has_key
,这是非常可靠的。
替换如下
1。
def check_if_running(username):
""" checks if self-control is already running. """
defaults = get_selfcontrol_settings(username)
return "BlockStartedDate" in defaults and not NSDate.distantFuture().isEqualToDate_(defaults["BlockStartedDate"])
2-4。
def check_config(config):
""" checks whether the config file is correct """
if not "username" in config:
exit_with_error("No username specified in config.")
if config["username"] not in get_osx_usernames():
exit_with_error(
"Username '{username}' unknown.\nPlease use your OSX username instead.\n" \
"If you have trouble finding it, just enter the command 'whoami'\n" \
"in your terminal.".format(
username=config["username"]))
if not "selfcontrol-path" in config:
exit_with_error("The setting 'selfcontrol-path' is required and must point to the location of SelfControl.")
if not os.path.exists(config["selfcontrol-path"]):
exit_with_error(
"The setting 'selfcontrol-path' does not point to the correct location of SelfControl. " \
"Please make sure to use an absolute path and include the '.app' extension, " \
"e.g. /Applications/SelfControl.app")
if not "block-schedules" in config:
exit_with_error("The setting 'block-schedules' is required.")
if len(config["block-schedules"]) == 0:
exit_with_error("You need at least one schedule in 'block-schedules'.")
if config.get("host-blacklist", None) is None:
print("WARNING:")
msg = "It is not recommended to directly use SelfControl's blacklist. Please use the 'host-blacklist' " \
"setting instead."
print(msg)
syslog.syslog(syslog.LOG_WARNING, msg)
该解决方案的正式资源在这里: https : //portingguide.readthedocs.io/en/latest/dicts.html
TL; DR是这样的:
some_dict.has_key('some key')
就是现在:
'some key' in some_dict
因此,在您的代码中:
return defaults.has_key("BlockStartedDate") and not NSDate.distantFuture().isEqualToDate_(defaults["BlockStartedDate"])
变为:
return "BlockStartedDate" in defaults and not NSDate.distantFuture().isEqualToDate_(defaults["BlockStartedDate"])
同样,如下行:
if not config.has_key("selfcontrol-path"):
# do something
变得像:
if "selfcontrol-path" not in config:
# do something
请注意,您也可以if not "selfcontrol-path" in config:
编写if not "selfcontrol-path" in config:
但是上面给出的示例被认为是更加Pythonic的,应该被优先使用。
在python3.7中测试。
tmp = {'a':1, 'b':2, 'c':3}
print(tmp.__contains__('a')) #True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.