2013-05-13 35 views
5

Như đã trình bày trong PEP435, một enum thể được định nghĩa theo cách này:Làm thế nào để có được các thuộc tính theo thứ tự chúng được khai báo trong một lớp Python?

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

Và kết quả enum members của Color có thể được lặp theo thứ tự định nghĩa: Color.red, Color.green, Color.blue.

Điều này nhắc tôi về số Form trong Django, trong đó các trường có thể được hiển thị theo thứ tự được khai báo trong lớp con Form. Họ thực hiện điều này bằng cách duy trì một bộ đếm trường, mỗi khi một trường mới được khởi tạo thì giá trị bộ đếm được tăng lên.

Nhưng trong định nghĩa của Color, chúng tôi không có thứ gì giống như FormField, làm cách nào chúng tôi có thể triển khai tính năng này?

Trả lời

10

Trong Python 3, bạn có thể tùy chỉnh không gian tên mà lớp được khai báo bằng metaclass. Ví dụ, bạn có thể sử dụng một OrderedDict:

from collections import OrderedDict 

class EnumMeta(type): 

    def __new__(mcls, cls, bases, d): 
     print(d) 
     return type.__new__(mcls, cls, bases, d) 

    @classmethod 
    def __prepare__(mcls, cls, bases): 
     return OrderedDict() 


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

này in

OrderedDict([('__module__', '__main__'), ('red', 1), ('green', 2), ('blue', 3)]) 
+0

Tôi tự hỏi liệu điều này có thể được thực hiện trong Python2.x hay không, để chúng tôi tạo một backport của 'enum'. – satoru

+0

Ồ, tôi không thấy câu trả lời của bạn, chính xác! –

+0

No. Bạn đang giảm xuống '' 'FormField''' kiểu hack ở đó. –

4

Trong Python 2.x bạn có thể sử dụng this horrible hack tôi đã viết để trả lời một câu hỏi hơi khác nhau, làm nền tảng cho chức năng này sắp xếp. Vì vậy, thực sự, bạn không thể. :-)

Các vấn đề liên quan