2

最初は次のようなことを考えていました:

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

しかし、range() 関数に渡すことができるように、EXIT_CODES の総数を正確に知る必要があることに気付きました。87 (任意) の EXIT_CODES があるとしましょう... 87 まで数えたくありません (難しいというわけではありません) が、より洗練されたソリューションを探しています。

助言がありますか ?

編集: EXIT_CODE は sys.exit に渡される負の int です。数値を書く代わりに、ある種の定数 (C の #defines や列挙型、Java の列挙型など) を使用することを好みます。

4

5 に答える 5

2

あなたが望むものは、C#または他の同様の言語での列挙に相当するPythonです。Pythonで「列挙型」を表すにはどうすればよいですか?いくつかの解決策を提供しますが、それでもあなたが持っているアイテムの数が必要です。編集: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
于 2010-09-16T23:17:17.877 に答える
1

質問の意味がわからないかもしれませんが、終了コードの辞書を作成して、目的の動作を関数に実装してみませんか?

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

(最後のものについては、辞書ベースのものと同様の機能を実装できます)

于 2010-09-16T23:53:09.677 に答える
1

否定的なステータスが sys.exit(); にとって理にかなっているとは限らないことに注意する必要があります。少なくとも 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}

通常の Unix システムで定義済みの値は、EXIT_FAILURE=1 および EXIT_SUCCESS=0 です。

補遺: ID の IDE 識別に関する懸念を考慮すると、次のようなこともできます。

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)

2 番目の編集: 離れられませんでした。名前を書いた順に値を割り当てるバリアントを次に示します。

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

明らかに、複雑さが増すことはエレガントではありませんが、機能します。

于 2010-09-17T00:05:21.400 に答える
1

私はこの質問を以前に見て、それを見なかったと思いますが、やるべきことの1つは辞書を使うことです。

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')
于 2010-09-27T02:12:24.390 に答える
0

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
于 2010-09-17T00:09:11.937 に答える