Все запутались в если и Элиф и попробовать


Я работаю на небольшую программу, чтобы добавить или удалить определенные записи из реестра Windows, и я уже совсем запутался, если и попробовать условия. Я потратил часы, охотящаяся за насекомыми, обычно логическими, пытаясь достичь того, что концептуально очень простой. Чем больше я работаю, и "улучшить" код так что он работает больше и больше условий, чем больше пытали и сложным, если анализы сделать, пока я не могу сказать, что больше вверх и вниз. Наверняка там должен быть лучший способ! (даже для моего маленького мозга)

Это все, что я пытаюсь сделать:

Когда его спросили, чтобы установить:

Если наши версии Python и каталог-установки в реестре: ничего не делать.
Если наши версии Python и различных каталог-установки: ничего не делать.
Если наша Python не существует, добавьте его.

Когда попросили убрать:

Если наша Python не существует: ничего не делать
Если наши версии Python и различных каталог-установки: ничего не делать.
Если наши версии Python и каталог-установки в реестре: удалить.

Но мой код только для удаления части выглядит как ниже ( все это здесь). Это работает, более или менее, но это просто не чувствует себя хорошо. Я не знаю, что делать, чтобы сделать его чище. Ваши мнения приветствуются. Спасибо.

def remove():
    ''' see if any existing registrations match our python version and register ours if not '''

    if CurrentUser:
        match = True if our_version in CurrentUser else False
        versions = CurrentUser
    elif AllUsers:
        match = True if our_version in AllUsers else False
        versions = AllUsers
    else:
        print '\nOur version (%s) not registered to "%s", skipping...' % (our_version, versions[our_version])

    try:
        if match:
            print '\nVersion matches ours, calling deRegisterPy...'
            deRegisterPy(pycore_regpath,our_version)
    except:
        raise

def deRegisterPy(pycore_regpath, version):
    ''' remove this python install from registry '''
    pycore_regpath = pycore_regpath + version   # e.g. 'SOFTWARE\Python\Pythoncore\2.7'
    try:
        reg = OpenKey(HKEY_LOCAL_MACHINE, pycore_regpath)
        installpath = QueryValue(reg, installkey) # win32
        if installpath == our_installpath:
            print '\nexisting python matches ours, removing...\n'
            # print '(%s vs %s)' % (installpath, our_installpath)
            for subkey in ['\\InstallPath', '\\PythonPath']:
                DeleteKey(HKEY_LOCAL_MACHINE, pycore_regpath + subkey)
            DeleteKey(HKEY_LOCAL_MACHINE, pycore_regpath)
            print "--- Python %s, %s is now removed!" % (our_version, our_installpath)
        CloseKey(reg)
    except EnvironmentError:
        print 'EnvironmentError', EnvironmentError()
        raise
        return
    except WindowsError:
        print "Strange, we've hit an exception, perhaps the following will say why:"
        print WindowsError()
        raise
        return
    CloseKey(reg)

# main
if args['action']=='install':
    install()
elif args['action']=='remove':
    remove()


1296
3
задан 6 октября 2011 в 11:10 Источник Поделиться
Комментарии
1 ответ

def remove():
''' see if any existing registrations match our python version and register ours if not '''

if CurrentUser:

Руководство по стилю Python запасы верблюжьего для имен классов. Если это глобальная константа должна быть функция current_user. Если ее не глобальная константа, она не должна быть доступна как глобальная переменная.

        match = True if our_version in CurrentUser else False

Просто используйте матч = our_version в currentUser с

        versions = CurrentUser
elif AllUsers:
match = True if our_version in AllUsers else False
versions = AllUsers

else:
print '\nOur version (%s) not registered to "%s", skipping...' % (our_version, versions[our_version])

try:
if match:
print '\nVersion matches ours, calling deRegisterPy...'
deRegisterPy(pycore_regpath,our_version)
except:
raise

Что??? попробуйте..только ничего не делает, если вы просто поднимаете ошибку сразу

def deRegisterPy(pycore_regpath, version):

Руководство по стилю Python рекомендует lower_case_with_underscores для имен функций

    ''' remove this python install from registry '''
pycore_regpath = pycore_regpath + version # e.g. 'SOFTWARE\Python\Pythoncore\2.7'
try:
reg = OpenKey(HKEY_LOCAL_MACHINE, pycore_regpath)
installpath = QueryValue(reg, installkey) # win32

Почему вы нашли время, чтобы указать, что ее с Win32 здесь?

        if installpath == our_installpath:
print '\nexisting python matches ours, removing...\n'
# print '(%s vs %s)' % (installpath, our_installpath)

Не оставляйте мертвого кода в комментариях

            for subkey in ['\\InstallPath', '\\PythonPath']:
DeleteKey(HKEY_LOCAL_MACHINE, pycore_regpath + subkey)
DeleteKey(HKEY_LOCAL_MACHINE, pycore_regpath)
print "--- Python %s, %s is now removed!" % (our_version, our_installpath)
CloseKey(reg)
except EnvironmentError:
print 'EnvironmentError', EnvironmentError()

Что ты пытаешься сделать здесь? Вы строите новый объект EnviromentError, а затем распечатать его. Но это бессмысленно, что нужно сделать

        raise

Если вы только собираетесь снова поднять ошибки, не много смысла в печати его в любом случае
вернуться

Ты понимаешь, что ничего после рейза будет исполнен, так что это возвращение будет иметь никакого эффекта?

    except WindowsError:
print "Strange, we've hit an exception, perhaps the following will say why:"
print WindowsError()

Вы, кажется, путают о том, как поймать ошибки, которые вы хотите:

except WindowsError as error:
print error

Но на самом деле вам не надо делать: просто дайте исключения летают и Python будет распечатать их, когда она выходит из-за ошибки

        raise
return

Опять же, возврата никогда не будет достигнут

    CloseKey(reg)

Если исключение происходит, это никогда не будет называться. Вы должны поместить его в блоке finally или что-то

# main
if args['action']=='install':
install()
elif args['action']=='remove':
remove()

Вы должны действительно поставить логику, как это в функцию main.

Любая моя переписывать весь файл. Тестирование. Но это должно дать вам представление о том, что вы можете сделать.

#!/usr/bin/env python

import sys
from _winreg import *

import argparse, sys
import os.path

PYTHON_VERSION = "%d.%d" % sys.version_info[0:2]

# the registry key paths we'll be looking at & using
PYCORE_REGISTRY_PATH = ("SOFTWARE","Python","Pythoncore")
INSTALL_KEY = "InstallPath"
PYTHON_KEY = "PythonPath"
PYTHONPATH = ";".join( os.path.join(sys.prefix, sub) for sub in ["", "Lib", "DLLs"])

class RegisteryKeyNotFound(Exception):
pass

class RegisteryKey(object):
def __init__(self, hive):
self._key = key

def _path_from(self, segments):
if not isinstance(segments, tuple):
segments = (segments,)

return "\\".join(segments)

def __getitem__(self, segments):
try:
subkey = _winreg.OpenKey(self._key, self._path_from(segments))
except WindowsError:
# should really check the error
# to make sure that key not found is the real problem
raise RegisteryKeyNotFound(path)
return RegisteryKey(subkey)

def get_or_create(self, segments):
subkey = _winreg.CreateKey(self._key, self._path_from(segments))
return RegisteryKey(subkey)

def value(self, segments):
return _winreg.QueryValue(self._key, self._path_from(segments))

def delete(self, segments):
_winreg.DeleteKey(self._key, self._path_from(segments))

def set_value(self, segments, value):
_winreg.SetValue(self._key, self._path_from(segments), REG_SZ, value)

def __iter__(self):
index = 0
while True:
try:
yield RegisteryKey(EnumKey(key, index))
except WindowsError:
# add check to make sure correct here was gotten
break
else:
index += 1

def __del__(self):
_winreg.CloseKey(self._key)

HIVE_LOCAL_MACHINE = RegisteryKey(HKEY_LOCAL_MACHINE)
HIVE_CURRENT_USER = RegisteryKey(HKEY_CURRENT_USER)

def get_existing(hive):
''' retrieve existing python registrations '''

try:
key = hive[PYCORE_REGISTRY_PATH]
except RegisteryKeyNotFound:
return {}

versions = {}
for version in key:
versions[version] = version.value(INSTALL_KEY) # e.g. {'2.7' = 'C:\\Python27'}

return versions

def register_python(version):
''' put this python install into registry '''
try:
reg = HIVE_LOCAL_MACHINE[PYCORE_REGISTRY_PATH][version]
except RegisteryKeyNotFound:
reg = HIVE_LOCAL_MACHINE.get_or_create(PYCORE_REGISTRY_PATH).get_or_create(version)
reg.set_value(INSTALL_KEY, sys.prefix)
reg.set_value(PYTHON_KEY, PYTHONPATH)
print "--- Python %s is now registered to %s!" % (PYTHON_VERSION, sys.prefix)
else:
print reg.value(INSTALL_KEY)

if reg.value(INSTALL_KEY) == sys.prefix and reg.value(PYTHON_KEY) == PYTHONPATH:
print "=== Python %s is already registered!" % (PYTHON_VERSION)
else:
print "*** Unable to register!"
print "*** You probably have another Python installation!"

def deregister_python(version):
''' remove this python install from registry '''
reg = HIVE_LOCAL_MACHINE[PYCORE_REGISTRY_PATH][version]
install_path = reg.value(INSTALL_KEY)
if install_path == sys.prefix:
print '\nexisting python matches ours, removing...\n'
for subkey in ['InstallPath', 'PythonPath']:
reg.delete(subkey)
reg.delete()
print "--- Python %s, %s is now removed!" % (PYTHON_VERSION, sys.prefix)

def install(installed_versions):
''' see if any existing registrations match our python version, and if not, register ours '''

print '\n...installing'

if PYTHON_VERSION in installed_versions:
print '\nOur version (%s) already registered to "%s", skipping...' % (PYTHON_VERSION, installed_versions[PYTHON_VERSION])
else:
print '\nPutting python from environment into registry...\n'
register_python()

def remove(installed_versions):
''' see if any existing registrations match our python version and register ours if not '''
#print args
if PYTHON_VERSION in installed_versions:
deregister_python()
else:
print '\nOur version (%s) not registered, skipping...' % (PYTHON_VERSION)

# @url http://stackoverflow.com/questions/4042452/display-help-message-with-python-argparse-when-script-is-called-without-any-argum
# display the usage message when it is called with no arguments
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)

def main():
parser=MyParser()
parser.add_argument('action', help='one of "install" or "remove" ')
args = parser.parse_args()

current_user_versions = get_existing(HIVE_CURRENT_USER)
local_machine_versions = get_existing(HIVE_LOCAL_MACHINE)

print '\nFound in Current User:'
for key, value in current_user_versions.items():
print "\t%s - %s" % (key, value)
print '\nFound in All Users:'
for key, value in local_machine_version.items():
print "\t%s - %s" % (key, value)

all_versions = {}
all_versions.update(current_user_versions)
all_versions.update(local_machine_versions)

if args.action == 'install':
install(all_versions)
elif args.action == 'remove':
remove(all_versions)
else:
print '\nInvalid action specified. I only understand "install" and "remove". '

if __name__ == '__main__':
main()

Некоторые заметки:


  1. Интерфейс _winreg довольно низком уровне. Вы можете сделать код намного понятнее, завернув его во что-то более подходящие для Python. Я только сделал первый шаг в интерфейсе, и это, вероятно, могло быть сделано намного лучше.

  2. Вы разделили currentUser и LocalMachine, но относился к ним точно так же. Код может быть упрощен путем их слияния в гигантский словарь версии

  3. вы удалить питон из значение LocalMachine, но не функция current_user. Это кажется странным, но я не менял.

2
ответ дан 7 октября 2011 в 01:10 Источник Поделиться