Как заменить has_key в python3? - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь установить Auto-SelfControl и застрял при выполнении этой команды:

sudo /usr/bin/python auto-selfcontrol.py

Отображается ошибка:

AttributeError: 'dict 'У объекта нет атрибута' has_key '

Я ищу решения и в итоге заменяю 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)

Ответы [ 4 ]

0 голосов
/ 29 мая 2019

Проверено в python3.7.

   tmp = {'a':1, 'b':2, 'c':3}
   print(tmp.__contains__('a')) #True
0 голосов
/ 24 января 2019

Официальный источник решения находится здесь: 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:, но приведенный выше пример считается более пифоническим и должен быть предпочтительным.

0 голосов
/ 24 января 2019

В то время как пошаговые решения в других ответах будут работать, этот подход ошибочен просто потому, что слишком легко сделать небольшую ошибку, пропустить место, которое требует исправления, и т. Д. Лучшее решение - просто использовать the 2to3 конвертер . Вы можете исправить все ваши файлы одним махом:

$ 2to3 -f has_key -w auto-selfcontrol.py

Выполняется только has_key fixer , который преобразуется из dict.has_key(key) в key in dict. Конечно, вы можете сделать это самостоятельно, но это тот случай, когда простые программные исправители работают просто отлично. Возможно, вы захотите запустить его без -f has_key, чтобы он применял все исправители одновременно, в случае каких-либо других критических изменений, которые применяются между Py2 и Py3.

2to3 обрабатывает практически все автоматически, за исключением изменений типа Py2 str (где это логическое решение кода о том, должен ли данный литерал str быть bytes или str в Py3) и целочисленное деление (где / может потребоваться изменить на //, в зависимости от того, является ли вычисление логическим делением с плавающей запятой или делением по полу). Но для has_key это довольно надежно.

0 голосов
/ 24 января 2019

Заменить следующим образом

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...