2017-05-14 15 views
5

Có cách nào tốt hơn để hỗ trợ Enums dưới dạng các đối số argparse hơn mẫu này không?Hỗ trợ cho các đối số Enum trong argparse

class SomeEnum(Enum): 
    ONE = 1 
    TWO = 2 

parser.add_argument('some_val', type=str, default='one', 
        choices=[i.name.lower() for i in SomeEnum]) 
... 
args.some_val = SomeEnum[args.some_val.upper()] 
+1

Đã có yêu cầu cho 'Enum' về lỗi/vấn đề Python. Tôi không nhớ nhiều sự nhiệt tình cho việc xử lý đặc biệt. Các lựa chọn như của bạn là một cách. Một hàm khác sẽ là một hàm 'type' tùy chỉnh. Điều đó có thể vừa kiểm tra vừa chuyển đổi. Tôi nghi ngờ bạn quen thuộc hơn với Enums hơn tôi. – hpaulj

+0

Tôi đã tự hỏi một chút nếu có thể lấy được một Enum tùy chỉnh, nó sẽ hoạt động như mong đợi khi được đặt thành 'type =' –

+0

Tham số 'type' là một hàm/có thể gọi được. Viết của riêng bạn mà có một chuỗi, và làm một cái gì đó với nó. Các kiểu phổ biến, 'int' và' float' là các hàm chuẩn làm 'int (" 123 ")' hoặc 'float (" 12.3 ")'. – hpaulj

Trả lời

7

Tôi thấy đây là một câu hỏi cũ, nhưng tôi chỉ đi qua cùng một vấn đề (Python 2.7) và dưới đây là cách tôi giải quyết nó:

from argparse import ArgumentParser 
from enum import Enum 

class Color(Enum): 
    red = 'red' 
    blue = 'blue' 
    green = 'green' 

    def __str__(self): 
     return self.value 

parser = ArgumentParser() 
parser.add_argument('color', type=Color, choices=list(Color)) 

opts = parser.parse_args() 
print 'your color was:', opts.color 

Lưu ý rằng việc xác định __str__ là cần thiết để có được ArgumentParser ' s giúp đầu ra để bao gồm các con người có thể đọc được (giá trị) của Color.

Một số lời gọi mẫu:

=> python enumtest.py blue 
your color was: blue 

=> python enumtest.py not-a-color 
usage: enumtest.py [-h] {blue,green,red} 
enumtest.py: error: argument color: invalid Color value: 'not-a-color' 

=> python enumtest.py -h 
usage: enumtest.py [-h] {blue,green,red} 

positional arguments: 
    {blue,green,red} 

Kể từ khi câu hỏi cụ thể số nguyên của OP như các giá trị, đây là một phiên bản sửa đổi một chút mà làm việc trong trường hợp đó (bằng cách sử dụng tên enum, chứ không phải là giá trị, như dòng lệnh args):

class Color(Enum): 
    red = 1 
    blue = 2 
    green = 3 

    def __str__(self): 
     return self.name 

parser = ArgumentParser() 
parser.add_argument('color', type=lambda color: Color[color], choices=list(Color)) 

Hạn chế duy nhất có thông số xấu gây ra sự xấu xí KeyError. Điều đó dễ dàng được giải quyết bằng cách thêm một chút mã nữa, chuyển đổi lambda thành một hàm thích hợp.

class Color(Enum): 
    red = 1 
    blue = 2 
    green = 3 

    def __str__(self): 
     return self.name 

    @staticmethod 
    def from_string(s): 
     try: 
      return Color[s] 
     except KeyError: 
      raise ValueError() 

parser = ArgumentParser() 
parser.add_argument('color', type=Color.from_string, choices=list(Color)) 
Các vấn đề liên quan