Hướng dẫn should enum be plural python? - enum có nên là python số nhiều không?

Bạn sử dụng số ít hoặc số nhiều để liệt kê? Tôi nghĩ rằng nó có ý nghĩa tốt nhất với số nhiều trong Tuyên bố

enum Weekdays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

... Nhưng tôi nghĩ rằng nó có ý nghĩa hơn với số ít khi sử dụng loại, ví dụ:

Weekday firstDayOfWeek = Weekday.Monday;

Tôi đã đọc một đề xuất ở đâu đó để sử dụng số ít trong các enum và số nhiều thông thường với cờ, nhưng tôi muốn nghe thêm một số ưu và nhược điểm.

2

Một đề xuất đến từ Hướng dẫn thiết kế .NET Framework, trang 59-60:

Sử dụng tên loại số ít cho một bảng liệt kê, trừ khi các giá trị của nó là trường bit. use a singular type name for an enumeration, unless its values are bit fields.

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...

Không sử dụng tên loại số nhiều cho một bảng liệt kê với các trường bit làm giá trị, còn được gọi là một lá cờ enum. use a plural type name for an enumeration with bit fields as values, also called a flags enum.

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}

Trong khung .NET, hầu hết các enum "bình thường" (ví dụ:

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
3) có tên và enum cờ số ít (ví dụ:
struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
4,
struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
5) có tên số nhiều. Nó có ý nghĩa, vì một giá trị của một lá cờ có thể đại diện cho nhiều mục nhưng đối với một enum không Flag, nó chỉ có thể đại diện cho một mục duy nhất.

Nói chung, tôi coi một định nghĩa enum là một định nghĩa loại, với các giá trị của enum là các giá trị khác nhau mà loại có thể có; Do đó, nó có một tên số ít:

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
6
struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
7

Đúng. Nếu bạn thực hiện trải nghiệm tinh thần khi thực hiện các enum như các lớp, thì thực tế là bạn sẽ sử dụng một tên số ít cho loại sẽ tiết lộ rằng việc sử dụng tên số ít cho các enum như vậy có ý nghĩa. Ví dụ.,

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;

...

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}

Đối với ai thích số nhiều trong enums, bạn sẽ đặt tên cho

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
8 đó?

Nói chung, tôi coi một định nghĩa enum là một định nghĩa loại, với các giá trị của enum là các giá trị khác nhau mà loại có thể có; Do đó, nó có một tên số ít:

enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };

Microsoft khuyên bạn nên sử dụng tên số ít để liệt kê trừ khi nó sử dụng thuộc tính

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
9. Và như được lấy từ cuốn sách Hướng dẫn thiết kế khung, bạn không nên làm tăng các tên loại liệt kê với Enum, Flags, v.v. Và bạn không nên tiền tố các giá trị liệt kê với từ viết tắt hoặc từ viết tắt như phổ biến với các liệt kê VB trở lại trong ngày.

1

Nó chủ quan và không quan trọng bạn sử dụng gì, miễn là bạn nhất quán (cá nhân tôi sử dụng số ít như nó mang theo từ các quy ước SQL của tôi)

3

  • Xóa khỏi các diễn đàn của tôi

  • Câu hỏi

  • Có các enum với danh từ đơn trong .NET như:

    Chủ đề

    Kiểu viền

    Và đồng thời Microsoft khuyên nên sử dụng danh từ số nhiều cho nó:

    http://msdn.microsoft.com/en-us/library/sbbt4032%28VS.80%29.aspx

    enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};

    Vậy lựa chọn tốt nhất là gì?


    Tôi tạo ra kính siêu phương tiện của tôi


    • Được chỉnh sửa Bythursday, ngày 19 tháng 4 năm 2012 7:51 AM Thursday, April 19, 2012 7:51 AM

Câu trả lời

  • Nếu bạn có thể hoặc các giá trị enum với nhau, hãy sử dụng số nhiều. Nếu không hãy sử dụng số ít.

    Nói cách khác, nếu bạn đang sử dụng thuộc tính [cờ] thì nó phải là số nhiều, nếu không thì nó phải là số ít. (IMHO!)

    [CHỈNH SỬA]

    Tôi tìm thấy hướng dẫn đặt tên Microsoft chính thức. Nó nói rằng:

    • Sử dụng tên số ít cho hầu hết các loại Enum, nhưng sử dụng tên số nhiều cho các loại enum là trường bit.Enum types, but use a plural name for Enum types that are bit fields.
    • Luôn thêm FlagsAttribution vào một loại enum trường bit.FlagsAttribute to a bit field Enum type.

    • Được đề xuất như câu trả lời của Bynico Boeythursday, ngày 19 tháng 4 năm 2012 7:57 AM Nico Boey Thursday, April 19, 2012 7:57 AM
    • Được chỉnh sửa Bymatthew Watsonthursday, ngày 19 tháng 4 năm 2012 8:18 sáng Matthew Watson Thursday, April 19, 2012 8:18 AM
    • Được đánh dấu là câu trả lời bysmartwhythursday, ngày 19 tháng 4 năm 2012 8:21 AM SmartWhy Thursday, April 19, 2012 8:21 AM

Tác giả: Barry Warsaw, Eli Bendersky, Ethan Furman Tình trạng: FinalType: Tiêu chuẩn theo dõi: 23-FEB-2013Python-Version::Barry Warsaw , Eli Bendersky , Ethan Furman Status:FinalType:Standards TrackCreated:23-Feb-2013Python-Version:3.4Post-History:23-Feb-2013, 02-May-2013Replaces:354Resolution:Python-Dev message
Mục lục
  • trừu tượng
  • Tình trạng của các cuộc thảo luận
  • Động lực
  • Mô -đun và tên loại
  • Đề xuất ngữ nghĩa cho loại liệt kê mới
    • Tạo ra một enum
    • Truy cập chương trình vào các thành viên liệt kê
    • Sao chép các thành viên và giá trị enum
    • So sánh
    • Cho phép các thành viên và thuộc tính của các liệt kê
    • Bị hạn chế phân lớp các bảng liệt kê
    • Intenum
    • Các mối liệt kê có nguồn gốc khác
    • Ngâm
    • API chức năng
  • Biến thể đề xuất
    • flufl.enum
    • Không phải chỉ định các giá trị cho enums
    • Sử dụng các tên hoặc biểu mẫu đặc biệt để tự động tham gia các giá trị enum
  • Sử dụng trường hợp trong thư viện tiêu chuẩn
  • Sự nhìn nhận
  • Người giới thiệu
  • Bản quyền

trừu tượng

Tình trạng của các cuộc thảo luận

Động lực

Tình trạng của các cuộc thảo luận

Động lực

Vấn đề phân chia quan trọng giữa

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 và
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 là liệu so sánh với số nguyên có ý nghĩa về mặt ngữ nghĩa hay không. Đối với hầu hết các cách sử dụng các liệt kê, nó là một tính năng để từ chối so sánh với các số nguyên; Các enum so sánh với các số nguyên dẫn, thông qua tính chuyển tiếp, để so sánh giữa các loại của các loại không liên quan, điều này không mong muốn trong hầu hết các trường hợp. Tuy nhiên, đối với một số mục đích sử dụng, khả năng tương tác lớn hơn với số nguyên là mong muốn. Chẳng hạn, đây là trường hợp thay thế các hằng số thư viện tiêu chuẩn hiện có (chẳng hạn như
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
7) bằng các bảng liệt kê.feature to reject comparison to integers; enums that compare to integers lead, through transitivity, to comparisons between enums of unrelated types, which isn’t desirable in most cases. For some uses, however, greater interoperability with integers is desired. For instance, this is the case for replacing existing standard library constants (such as
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
7) with enumerations.

Thảo luận thêm vào cuối tháng 4 năm 2013 đã dẫn đến kết luận rằng các thành viên liệt kê nên thuộc loại enum của họ:

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
8. Guido đã tuyên bố một quyết định về vấn đề này [5], cũng như các vấn đề liên quan là không cho phép phân lớp các enum [6], trừ khi họ xác định không có thành viên liệt kê [7].

PEP đã được Guido chấp nhận vào ngày 10 tháng 5 năm 2013 [1].

Động lực

[Dựa trên một phần vào động lực được nêu trong PEP 354]

Các thuộc tính của một liệt kê rất hữu ích để xác định một tập hợp các giá trị không đổi liên quan, có thể có ý nghĩa ngữ nghĩa. Các ví dụ kinh điển là những ngày trong tuần (Chủ nhật đến thứ bảy) và các lớp đánh giá trường học (‘A, thông qua‘ D, và ‘F,). Các ví dụ khác bao gồm các giá trị trạng thái lỗi và trạng thái trong một quy trình được xác định.

Có thể chỉ cần xác định một chuỗi các giá trị của một số loại cơ bản khác, chẳng hạn như

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
2 hoặc
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
0, để biểu thị các giá trị tùy ý riêng biệt. Tuy nhiên, một bảng liệt kê đảm bảo rằng các giá trị như vậy khác biệt với bất kỳ giá trị nào khác bao gồm, quan trọng là các giá trị trong các bảng liệt kê khác và các hoạt động mà không có ý nghĩa (Thời gian thứ tư hai lần) không được xác định cho các giá trị này. Nó cũng cung cấp một biểu diễn in có thể in thuận tiện của các giá trị enum mà không yêu cầu lặp lại tẻ nhạt trong khi xác định chúng (tức là không
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
1).

Mô -đun và tên loại

Chúng tôi đề xuất thêm một mô -đun có tên

enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
2 vào thư viện tiêu chuẩn. Loại chính tiếp xúc với mô -đun này là
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4. Do đó, để nhập mã người dùng loại
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 sẽ chạy:

>>> from enum import Enum

Đề xuất ngữ nghĩa cho loại liệt kê mới

Tạo ra một enum

Các liệt kê được tạo bằng cú pháp lớp, giúp chúng dễ đọc và viết. Một phương pháp tạo thay thế được mô tả trong API chức năng. Để xác định một liệt kê, lớp con

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 như sau:

>>> from enum import Enum
>>> class Color(Enum):
...     red = 1
...     green = 2
...     blue = 3

Một lưu ý về danh pháp: Chúng tôi gọi

enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
6 là một bảng liệt kê (hoặc enum) và
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
7,
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
8 là các thành viên liệt kê (hoặc thành viên Enum). Các thành viên liệt kê cũng có các giá trị (giá trị của
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
7 là
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
0, v.v.)
: we call
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
6 an enumeration (or enum) and
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
7,
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
8 are enumeration members (or enum members). Enumeration members also have values (the value of
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
7 is
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
0, etc.)

Các thành viên liệt kê có các biểu diễn chuỗi có thể đọc được của con người:

Weekday firstDayOfWeek = Weekday.Monday;
0

Trong khi

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
1 của họ có thêm thông tin:

Weekday firstDayOfWeek = Weekday.Monday;
1

Loại thành viên liệt kê là bảng liệt kê mà nó thuộc về:

Weekday firstDayOfWeek = Weekday.Monday;
2

Enums cũng có một tài sản chỉ chứa tên mặt hàng của họ:

Weekday firstDayOfWeek = Weekday.Monday;
3

Tái liệt trình hỗ trợ lặp lại, theo thứ tự định nghĩa:

Weekday firstDayOfWeek = Weekday.Monday;
4

Các thành viên liệt kê có thể băm, vì vậy chúng có thể được sử dụng trong từ điển và bộ:

Weekday firstDayOfWeek = Weekday.Monday;
5

Truy cập chương trình vào các thành viên liệt kê

Đôi khi, nó rất hữu ích để truy cập các thành viên trong các lập trình theo chương trình (nghĩa là các tình huống trong đó

enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
7 won đã làm vì màu chính xác không được biết đến trong thời gian viết chương trình).
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 cho phép truy cập như vậy:

Weekday firstDayOfWeek = Weekday.Monday;
6

Nếu bạn muốn truy cập các thành viên Enum theo tên, hãy sử dụng quyền truy cập mục:

Weekday firstDayOfWeek = Weekday.Monday;
7

Sao chép các thành viên và giá trị enum

Có hai thành viên enum có cùng tên là không hợp lệ:

Weekday firstDayOfWeek = Weekday.Monday;
8

Tuy nhiên, hai thành viên ENUM được phép có cùng giá trị. Cho hai thành viên A và B có cùng giá trị (và đầu tiên được xác định), B là bí danh đối với A. Tra cứu giá trị của giá trị của A và B sẽ trả về A. Tra cứu tên B của B cũng sẽ trả về A:

Weekday firstDayOfWeek = Weekday.Monday;
9

Lặp lại các thành viên của một enum không cung cấp các bí danh:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
0

Thuộc tính đặc biệt

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
4 là một tên ánh xạ từ điển được đặt hàng cho các thành viên. Nó bao gồm tất cả các tên được xác định trong bảng liệt kê, bao gồm các bí danh:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
1

Thuộc tính

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
4 có thể được sử dụng để truy cập chương trình chi tiết cho các thành viên liệt kê. Ví dụ: tìm tất cả các bí danh:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
2

So sánh

Các thành viên liệt kê được so sánh bằng danh tính:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
3

So sánh được đặt hàng giữa các giá trị liệt kê không được hỗ trợ. Enums không phải là số nguyên (nhưng xem intenum bên dưới):

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
4

So sánh bình đẳng được xác định mặc dù:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
5

So sánh với các giá trị không kích thích sẽ luôn so sánh không bằng nhau (một lần nữa,

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 được thiết kế rõ ràng để hoạt động khác nhau, xem bên dưới):

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
6

Cho phép các thành viên và thuộc tính của các liệt kê

Các ví dụ trên sử dụng số nguyên cho các giá trị liệt kê. Sử dụng số nguyên ngắn và tiện dụng (và được cung cấp theo mặc định bởi API chức năng), nhưng không được thực thi nghiêm ngặt. Trong phần lớn các trường hợp sử dụng, người ta không quan tâm đến giá trị thực tế của một liệt kê là gì. Nhưng nếu giá trị là quan trọng, bảng liệt kê có thể có các giá trị tùy ý.

Các bảng liệt kê là các lớp Python, và có thể có các phương pháp và phương pháp đặc biệt như bình thường. Nếu chúng ta có sự liệt kê này:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
7

Then:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
8

Các quy tắc cho những gì được phép như sau: tất cả các thuộc tính được xác định trong một bảng liệt kê sẽ trở thành thành viên của bảng liệt kê này, ngoại trừ __dunder__ tên và mô tả [9]; Phương pháp là mô tả quá.

Bị hạn chế phân lớp các bảng liệt kê

Phân lớp một liệt kê chỉ được phép nếu việc liệt kê không xác định bất kỳ thành viên nào. Vì vậy, điều này bị cấm:

public enum ConsoleColor {
  Black,
  Blue,
  Cyan,
  ...
9

Nhưng điều này được cho phép:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
0

Lý do cho quyết định này được đưa ra bởi Guido trong [6]. Cho phép các phân lớp các enum xác định các thành viên sẽ dẫn đến vi phạm một số bất biến quan trọng của các loại và trường hợp. Mặt khác, thật hợp lý khi cho phép chia sẻ một số hành vi phổ biến giữa một nhóm các liệt kê và phân lớp các bảng điều khiển trống cũng được sử dụng để thực hiện

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3.

Intenum

Một biến thể của

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 được đề xuất cũng là một lớp con của
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
2. Các thành viên của
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 có thể được so sánh với các số nguyên; Bằng cách mở rộng, các loại thuốc của các loại khác nhau cũng có thể được so sánh với nhau:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
1

Tuy nhiên, họ vẫn có thể được so sánh với

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
2

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 Các giá trị hoạt động như số nguyên theo những cách khác mà bạn mong đợi:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
3

Đối với đại đa số mã,

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 được khuyến khích mạnh mẽ, vì
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 phá vỡ một số lời hứa ngữ nghĩa về một bảng liệt kê (bằng cách so sánh với các số nguyên, và do đó bằng cách chuyển tiếp đến các liệt kê không liên quan khác). Nó chỉ nên được sử dụng trong những trường hợp đặc biệt mà không có lựa chọn nào khác; Ví dụ, khi các hằng số nguyên được thay thế bằng các bảng liệt kê và khả năng tương thích ngược là cần thiết với mã vẫn mong đợi số nguyên.

Các mối liệt kê có nguồn gốc khác

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 sẽ là một phần của mô -đun
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
2. Tuy nhiên, sẽ rất đơn giản để thực hiện độc lập:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
4

Điều này cho thấy cách các liệt kê có nguồn gốc tương tự có thể được xác định, ví dụ A

>>> from enum import Enum
7 trộn trong
enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

enum CoffeeSize { SMALL, MEDIUM, LARGE };
0 thay vì
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
2.

Một số quy tắc:

  1. Khi phân lớp enum, các loại hỗn hợp phải xuất hiện trước khi tự kết nối trong chuỗi các cơ sở, như trong ví dụ
    void func (Weekday *day)
    {
       if (day == &SUNDAY)
           ...
    }
    
    3 ở trên.
  2. Mặc dù enum có thể có các thành viên thuộc bất kỳ loại nào, một khi bạn trộn vào một loại bổ sung, tất cả các thành viên phải có giá trị của loại đó, ví dụ:
    void func (Weekday *day)
    {
       if (day == &SUNDAY)
           ...
    }
    
    2 ở trên. Hạn chế này không áp dụng cho các bản phối mà chỉ thêm các phương thức và don lồng chỉ định một loại dữ liệu khác như
    void func (Weekday *day)
    {
       if (day == &SUNDAY)
           ...
    }
    
    2 hoặc
    enum Weekday { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
    
    enum CoffeeSize { SMALL, MEDIUM, LARGE };
    
    0.

Ngâm

Tái lập có thể được ngâm và không được giải thích:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
5

Các hạn chế thông thường đối với Pickling áp dụng: Các enum có thể chọn phải được xác định ở cấp cao nhất của một mô -đun, vì việc không bị ràng buộc đòi hỏi chúng phải được nhập từ mô -đun đó.

API chức năng

Lớp

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 có thể gọi được, cung cấp API chức năng sau:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
6

Các ngữ nghĩa của API này giống với

>>> from enum import Enum
>>> class Color(Enum):
...     red = 1
...     green = 2
...     blue = 3
5. Đối số đầu tiên của cuộc gọi đến
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 là tên của bảng liệt kê. Các enum pickling được tạo với API chức năng sẽ hoạt động trên CPython và Pypy, nhưng đối với IronPython và Jython, bạn có thể cần chỉ định tên mô -đun một cách rõ ràng như sau:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
7

Đối số thứ hai là nguồn gốc của tên thành viên liệt kê. Nó có thể là một chuỗi các tên được phân tách bằng khoảng trắng, một chuỗi các tên, một chuỗi các bộ 2 với các cặp khóa/giá trị hoặc ánh xạ (ví dụ: từ điển) của các tên thành các giá trị. Hai tùy chọn cuối cùng cho phép gán các giá trị tùy ý cho các bảng điều khiển; Các số nguyên tăng tự động khác bắt đầu với 1. Một lớp mới có nguồn gốc từ

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4 được trả về. Nói cách khác, nhiệm vụ trên cho
>>> from enum import Enum
>>> class Color(Enum):
...     red = 1
...     green = 2
...     blue = 3
8 tương đương với:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
8

Lý do mặc định đến

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
0 là số bắt đầu chứ không phải
Weekday firstDayOfWeek = Weekday.Monday;
00 là
Weekday firstDayOfWeek = Weekday.Monday;
00 là
Weekday firstDayOfWeek = Weekday.Monday;
02 theo nghĩa boolean, nhưng tất cả các thành viên enum đều đánh giá thành
Weekday firstDayOfWeek = Weekday.Monday;
03.

Biến thể đề xuất

Một số biến thể đã được đề xuất trong các cuộc thảo luận trong danh sách gửi thư. Ở đây, một số trong những cái phổ biến hơn.

flufl.enum

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
1 là triển khai tham chiếu mà PEP này ban đầu dựa trên. Cuối cùng, nó đã được quyết định chống lại sự bao gồm của
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
1 vì thiết kế của nó đã tách các thành viên liệt kê khỏi các liệt kê, vì vậy cái trước không phải là trường hợp của cái sau. Thiết kế của nó cũng cho phép rõ ràng các bảng liệt kê phân lớp để mở rộng chúng với nhiều thành viên hơn (do sự phân tách thành viên/enum, loại bất biến không bị vi phạm trong
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
1 với sơ đồ như vậy).

Không phải chỉ định các giá trị cho enums

Michael Foord đã đề xuất (và Tim Delaney đã cung cấp một triển khai bằng chứng về khái niệm) để sử dụng ma thuật Metaclass giúp điều này có thể:

[Flags]
public enum ConsoleModifiers {
  Alt,
  Control,
  Shift
}
9

Các giá trị thực sự chỉ được gán khi lần đầu tiên nhìn lên.

Ưu điểm: Cú pháp Cleaner yêu cầu gõ ít hơn cho một nhiệm vụ rất phổ biến (chỉ liệt kê các tên liệt kê mà không quan tâm đến các giá trị).

Nhược điểm: Liên quan đến nhiều phép thuật trong việc thực hiện, điều này làm cho ngay cả định nghĩa của các enum như vậy khi lần đầu tiên nhìn thấy. Bên cạnh đó, rõ ràng là tốt hơn tiềm ẩn.

Sử dụng các tên hoặc biểu mẫu đặc biệt để tự động tham gia các giá trị enum

Một cách tiếp cận khác để tránh chỉ định các giá trị enum là sử dụng tên hoặc biểu mẫu đặc biệt để tự động gán chúng. Ví dụ:

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
0

Linh hoạt hơn:

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
1

Một số biến thể về chủ đề này:

  1. Một tên đặc biệt
    Weekday firstDayOfWeek = Weekday.Monday;
    
    07 được nhập từ gói Enum.
  2. Georg Brandl đề xuất Ellipsis (
    Weekday firstDayOfWeek = Weekday.Monday;
    
    08) thay vì
    Weekday firstDayOfWeek = Weekday.Monday;
    
    09 để đạt được hiệu ứng tương tự.

Ưu điểm: Không cần phải nhập thủ công các giá trị. Làm cho nó dễ dàng hơn để thay đổi enum và mở rộng nó, đặc biệt là đối với các liệt kê lớn.

Nhược điểm: thực sự dài hơn để gõ trong nhiều trường hợp đơn giản. Đối số của rõ ràng so với ngầm áp dụng ở đây là tốt.

Sử dụng trường hợp trong thư viện tiêu chuẩn

Thư viện tiêu chuẩn Python có nhiều nơi sử dụng các enum sẽ có lợi để thay thế các thành ngữ khác hiện đang được sử dụng để đại diện cho chúng. Các cách sử dụng như vậy có thể được chia thành hai loại: các hằng số đối diện với mã người dùng và hằng số bên trong.

Các hằng số đối mặt với mã người dùng như hằng số mô-đun

Weekday firstDayOfWeek = Weekday.Monday;
10,
Weekday firstDayOfWeek = Weekday.Monday;
11, chế độ làm tròn thập phân và mã lỗi HTML có thể yêu cầu tương thích ngược vì mã người dùng có thể mong đợi số nguyên.
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
3 Như được mô tả ở trên cung cấp các ngữ nghĩa cần thiết; Là một lớp con của
void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
2, nó không ảnh hưởng đến mã người dùng mong đợi số nguyên, trong khi mặt khác cho phép các biểu diễn có thể in được cho các giá trị liệt kê:

struct Weekday {};

const Weekday SUNDAY;
const Weekday MONDAY;
const Weekday TUESDAY;
2

Các hằng số bên trong không được nhìn thấy bởi mã người dùng nhưng được sử dụng bên trong các mô -đun stdlib. Chúng có thể được thực hiện với

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
4. Một số ví dụ được phát hiện bởi một phần rất nhỏ thông qua stdlib:
Weekday firstDayOfWeek = Weekday.Monday;
15,
Weekday firstDayOfWeek = Weekday.Monday;
16,
Weekday firstDayOfWeek = Weekday.Monday;
17,
Weekday firstDayOfWeek = Weekday.Monday;
18,
Weekday firstDayOfWeek = Weekday.Monday;
19,
Weekday firstDayOfWeek = Weekday.Monday;
20,
Weekday firstDayOfWeek = Weekday.Monday;
21.

Ngoài ra, nhìn vào mã của thư viện xoắn, có nhiều trường hợp sử dụng để thay thế các hằng số trạng thái bên trong bằng enums. Điều tương tự cũng có thể nói về rất nhiều mã kết nối mạng (đặc biệt là triển khai các giao thức) và cũng có thể thấy trong các giao thức thử nghiệm được viết với thư viện tulip.

Sự nhìn nhận

PEP này ban đầu được đề xuất bao gồm gói

void func (Weekday *day)
{
   if (day == &SUNDAY)
       ...
}
1 [8] bởi Barry Warsaw vào stdlib, và được lấy cảm hứng từ những phần lớn của nó. Ben Finney là tác giả của PEP 354 trước đó.

Người giới thiệu

Bản quyền

Tài liệu này đã được đặt trong phạm vi công cộng.

Nên được đặt tên là số nhiều?

Enums trong Java (và có lẽ là enum nói chung) nên là số ít.Suy nghĩ là bạn không chọn nhiều giao thức, mà là một giao thức của các lựa chọn có thể trong danh sách các giá trị.should be singular. The thinking is that you're not selecting multiple Protocols, but rather one Protocol of the possible choices in the list of values.

Enum nên là số ít hay số nhiều?

Chi tiết quy tắc.Quy tắc này thực thi tất cả các enum TypeScript là số ít.Một lỗi sẽ xảy ra nếu enum được xác định với một tên số nhiều.This rule enforces all TypeScript enums to be singular. An error will occur if the enum is defined with a pluralized name.

Làm thế nào nên đặt tên cho enum?

Enums là các loại, vì vậy chúng nên được đặt tên bằng cách sử dụng các lớp Uppercamelcase.Các giá trị enum là hằng số, vì vậy chúng nên được đặt tên bằng cách sử dụng LowerCamelCase như hằng số hoặc all_caps nếu mã của bạn sử dụng kiểu đặt tên kế thừa đó.using UpperCamelCase like classes. The enum values are constants, so they should be named using lowerCamelCase like constants, or ALL_CAPS if your code uses that legacy naming style.

Có nên Enums được viết hoa Python?

Theo quy ước, tên liệt kê bắt đầu bằng một chữ cái viết hoa và là số ít.Mô -đun Enum được sử dụng để tạo các liệt kê trong Python.. The enum module is used for creating enumerations in Python.