代码之家  ›  专栏  ›  技术社区  ›  Andrei Ciobanu

如何在python中实现“退出代码”?

  •  2
  • Andrei Ciobanu  · 技术社区  · 15 年前

    起初我想做一些事情,比如:

    #EXIT CODES
    class ExitCode(object):
        (USERHOME_INVALID, \
        USERHOME_CANNOT_WRITE, \
        USERHOME_CANNOT_READ, \
        BASHRC_INVALID) = range(-1, -5, -1)
    

    有什么建议吗?

    退出代码是一个负整数,它将被传递给系统出口. 与其写数字,我更喜欢使用某种常量(比如C中的#defines或enums,或者Java中的enums)。

    5 回复  |  直到 15 年前
        1
  •  2
  •   Community Mohan Dere    9 年前

    听起来您想要的是Python,相当于C或其他类似语言中的枚举。 How can I represent an 'Enum' in Python? 提供了几种解决方案,尽管它们仍然需要您拥有的项目数。 编辑: How can I represent an 'Enum' in Python? 方式 更好。

    或者你可以尝试这样的方法(虽然可能不是最好的解决方案):

    class _ExitCode:
        _exit_codes=["EXIT_CODE","EXIT_CODE_TWO"]
        def __getattr__(self, name):
            if name in _ExitCode._exit_codes:
                return -(_ExitCode._exit_codes.index(name)+1)
            raise AttributeError("Exit code %s not found" % name)
    
    ExitCode=_ExitCode()
    print ExitCode.EXIT_CODE #-1
    
        2
  •  1
  •   Escualo    15 年前

    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
    

    (对于最后一个,您可以实现一个类似于基于字典的函数)

        3
  •  1
  •   Yann Vernier    15 年前

    我必须指出的是,一点也不确定消极的状态对我们来说是有意义的系统出口();至少在Linux上,它将被解释为无符号8位值(范围0-255)。对于枚举类型,可以执行以下操作:

    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()
    

    显然,日益增长的复杂性是不雅观的,但它确实起作用。

        4
  •  1
  •   aaronasterling    15 年前

    我想我之前看过这个问题,但没有看到它,但一个明显的做法是使用dict。

    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')
    
        5
  •  0
  •   martineau    15 年前

    可以使用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