您如何实施';退出代码';用python?
起初我想做一些事情,比如:您如何实施';退出代码';用python?,python,exit-code,Python,Exit Code,起初我想做一些事情,比如: #EXIT CODES class ExitCode(object): (USERHOME_INVALID, \ USERHOME_CANNOT_WRITE, \ USERHOME_CANNOT_READ, \ BASHRC_INVALID) = range(-1, -5, -1) class ExitStatus: pass for code, name in enumerate("Success Failure CriticalF
#EXIT CODES
class ExitCode(object):
(USERHOME_INVALID, \
USERHOME_CANNOT_WRITE, \
USERHOME_CANNOT_READ, \
BASHRC_INVALID) = range(-1, -5, -1)
class ExitStatus: pass
for code, name in enumerate("Success Failure CriticalFailure".split()):
setattr(ExitStatus, name, code)
>>> ExitStatus.__dict__
{'CriticalFailure': 2, 'Failure': 1, '__module__': '__main__',
'__doc__': None, 'Success': 0}
class EnumItem: pass
def adjustEnum(enum):
value=0
enumdict=enum.__dict__
for k,v in enumdict.items():
if isinstance(v,int):
if v>=value:
value=v+1
for k,v in enumdict.items():
if v is EnumItem:
enumdict[k]=value
value+=1
class ExitStatus:
Success=0
Failure=EnumItem
CriticalFailure=EnumItem
adjustEnum(ExitStatus)
但是我意识到,我必须准确地知道EXIT_代码的总数,这样我才能将它传递给range()函数。假设我有87个(任意)退出代码。。。我不想数到87(这并不难),但我正在寻找一个更优雅的解决方案
有什么建议吗
编辑:
EXIT_代码是将传递给sys.EXIT的负整数。与其写数字,我更喜欢使用某种常量(比如C中的#defines或enum,或者Java中的enum)。听起来你想要的是与C或其他类似语言中的枚举相当的Python。提供多种解决方案,尽管它们仍然需要您拥有的项目数量。 编辑:看起来好多了 或者您可以尝试类似的方法(但可能不是最好的解决方案):
也许我不明白这个问题,但为什么不简单地编写一个退出代码字典,并在函数中实现所需的行为呢
EXIT_CODES = dict(SUCCESS=0,
USER_NAME_INVALID=-1,
OTHER_ERROR=-2)
def exit(code):
try:
return EXIT_CODES[code]
except KeyError:
raise KeyError("exit code %s is not implemented" % code)
所以你可以像这样使用它
# some computation goes here
return exit("SUCCESS")
如果您想“自动”分配数字(我不建议这样做),您只需创建一个退出代码列表并返回索引的负数:
EXIT_CODES = ['SUCCESS', 'ERROR_1', 'ERROR_2']
return -EXIT_CODES.index('ERROR_1')
# will return -1
(对于最后一个,您可以实现一个与基于字典的函数类似的函数)我必须注意,对于sys.exit(),根本不确定负状态是否有意义;至少在Linux上,它将被解释为无符号8位值(范围0-255)。对于枚举类型,可以执行以下操作:
#EXIT CODES
class ExitCode(object):
(USERHOME_INVALID, \
USERHOME_CANNOT_WRITE, \
USERHOME_CANNOT_READ, \
BASHRC_INVALID) = range(-1, -5, -1)
class ExitStatus: pass
for code, name in enumerate("Success Failure CriticalFailure".split()):
setattr(ExitStatus, name, code)
>>> ExitStatus.__dict__
{'CriticalFailure': 2, 'Failure': 1, '__module__': '__main__',
'__doc__': None, 'Success': 0}
class EnumItem: pass
def adjustEnum(enum):
value=0
enumdict=enum.__dict__
for k,v in enumdict.items():
if isinstance(v,int):
if v>=value:
value=v+1
for k,v in enumdict.items():
if v is EnumItem:
enumdict[k]=value
value+=1
class ExitStatus:
Success=0
Failure=EnumItem
CriticalFailure=EnumItem
adjustEnum(ExitStatus)
结果是:
#EXIT CODES
class ExitCode(object):
(USERHOME_INVALID, \
USERHOME_CANNOT_WRITE, \
USERHOME_CANNOT_READ, \
BASHRC_INVALID) = range(-1, -5, -1)
class ExitStatus: pass
for code, name in enumerate("Success Failure CriticalFailure".split()):
setattr(ExitStatus, name, code)
>>> ExitStatus.__dict__
{'CriticalFailure': 2, 'Failure': 1, '__module__': '__main__',
'__doc__': None, 'Success': 0}
class EnumItem: pass
def adjustEnum(enum):
value=0
enumdict=enum.__dict__
for k,v in enumdict.items():
if isinstance(v,int):
if v>=value:
value=v+1
for k,v in enumdict.items():
if v is EnumItem:
enumdict[k]=value
value+=1
class ExitStatus:
Success=0
Failure=EnumItem
CriticalFailure=EnumItem
adjustEnum(ExitStatus)
正常Unix系统中的预定义值为EXIT_FAILURE=1和EXIT_SUCCESS=0
附录:考虑到IDE标识标识符的问题,还可以做如下操作:
#EXIT CODES
class ExitCode(object):
(USERHOME_INVALID, \
USERHOME_CANNOT_WRITE, \
USERHOME_CANNOT_READ, \
BASHRC_INVALID) = range(-1, -5, -1)
class ExitStatus: pass
for code, name in enumerate("Success Failure CriticalFailure".split()):
setattr(ExitStatus, name, code)
>>> ExitStatus.__dict__
{'CriticalFailure': 2, 'Failure': 1, '__module__': '__main__',
'__doc__': None, 'Success': 0}
class EnumItem: pass
def adjustEnum(enum):
value=0
enumdict=enum.__dict__
for k,v in enumdict.items():
if isinstance(v,int):
if v>=value:
value=v+1
for k,v in enumdict.items():
if v is EnumItem:
enumdict[k]=value
value+=1
class ExitStatus:
Success=0
Failure=EnumItem
CriticalFailure=EnumItem
adjustEnum(ExitStatus)
第二次编辑:无法逃避。这里有一个变量,它按照您编写名称的顺序分配值
class EnumItem:
serial=0
def __init__(self):
self.serial=self.__class__.serial
self.__class__.serial+=1
def adjustEnum(enum):
enumdict=enum.__dict__
value=0
unknowns={}
for k,v in enumdict.items():
if isinstance(v,int):
if v>=value:
value=v+1
elif isinstance(v,EnumItem):
unknowns[v.serial]=k
for i,k in sorted(unknowns.items()):
enumdict[k]=value
value+=1
return enum
@adjustEnum
class ExitStatus:
Success=0
Failure=EnumItem()
CriticalFailure=EnumItem()
显然,日益增长的复杂性是不雅观的,但它确实有效。您可以使用Python动态创建变量(或类属性)。比如说
ExitCodes = '''USERHOME_INVALID, USERHOME_CANNOT_WRITE,
USERHOME_CANNOT_READ, BASHRC_INVALID'''
for i, s in enumerate(ExitCodes.split(','), 1):
exec('%s = %d' % (s.strip(), -i))
print USERHOME_INVALID
print USERHOME_CANNOT_WRITE
print USERHOME_CANNOT_READ
print BASHRC_INVALID
sys.exit(USERHOME_INVALID)
>>> -1
>>> -2
>>> -3
>>> -4
我想我之前看过这个问题,但没有看到,但一件显而易见的事情是使用口述
def make_exit_codes(*exit_codes):
return dict((name, -value - 1) for name, value in enumerate(exit_codes))
EXIT_CODES = make_exit_codes('USERHOME_INVALID', 'USERHOME_CANNOT_WRITE',
'USERHOME_CANNOT_READ', 'BASHRC_INVALID')
只是一个注释-你不需要括号中的反斜杠。这并不重要,但它们是多余的,不是真正的“Pythonic”。问题是dict包含的值会自动递增。我不想手动写入0,-1,-2,…,-87,然后意识到我必须重新组合它们。请不要过于急切地使用exec()之类的东西。您可能也可以使用
globals()。\uuuuu setitem\uuuu(s,-i)
。如果没有其他人对它进行了投票,那么这不值得投下一票,但是使用exec
应该位于列表的底部。l33tnerd的解决方案要优雅得多。“愚蠢的一致性是小头脑的妖怪……”这意味着,我相信,你可以根据具体情况自己决定。我实际上喜欢这个解决方案。缺点是我当前使用的IDE(Eclipse和PyDev)无法识别执行变量,因为它们是在运行时声明的。@Andrei Ciobanu。从未想过这一点——我猜需要一个非常智能的Python感知IDE来识别在运行时创建的标识符,在某些情况下甚至不可能。然而,我怀疑你所说的对目前发布的大多数答案也是正确的。感谢您指出另一个需要考虑的权衡。