Tôi có nên tránh các biến toàn cục trong python không?

Tôi tin tưởng điều này mạnh mẽ đến mức tôi nghĩ rằng các ngôn ngữ nên yêu cầu khai báo và truy cập vào các biến toàn cục để được bao bọc trong unsafe_and_evil. Ví dụ

// foo.cpp
unsafe_and_evil {
    int g_evil = 0;
}

void IncrementGlobal[int v] {
    unsafe_and_evil {
        g_evil += v;
    }
}

Rust có từ khóa unsafe. Điều này không đủ mạnh. Trạng thái toàn cầu có thể thay đổi vừa không an toàn vừa xấu xa. Các lập trình viên thêm các biến toàn cầu là xấu và nên cảm thấy tồi tệ

Điều này đã được nói về rất nhiều. Tôi sẽ không liệt kê tất cả các lý do. Tuy nhiên, đây là một vài điểm lấy cảm hứng từ các trường hợp tôi gặp phải gần đây

Thứ tự khởi tạo tĩnh thất bại là một khẩu súng lục C++ nổi tiếng. Cách khắc phục tốt nhất là "đừng làm thế". Thứ tự tắt máy cũng có vấn đề

Thư viện động Windows và Thư viện chia sẻ Linux hoạt động khác nhau. Windows .dll là một hộp được đóng gói tốt với API mỏng. Linux ________ 8 mặc định là một API béo để hiển thị chi tiết triển khai cho các thư viện khác. Windows khiến việc chia sẻ các biến toàn cục trên .dlls trở nên rất khó khăn. Linux cho phép và thậm chí khuyến khích các biến toàn cầu được chia sẻ. Đối phó với điều này là một nỗi đau cho dù bạn thích nền tảng nào hơn. Nếu bạn không có biến toàn cầu thì đó không phải là vấn đề

Các biến toàn cầu áp đặt các ràng buộc. Một thư viện dựa trên các biến toàn cục có thể buộc bạn phải sử dụng một singleton. Tôi đã sử dụng

// foo.cpp
static int evil_1; 
int evil_2; 

void DoStuff[] {
    static int evil_3;
    thread_local int evil_4; 
}

// foo.h
extern int evil_5; 
int evil_6;

struct Foo {
    static int evil_7; 
};
0 để nhúng python vào một dự án. Do sử dụng các biến toàn cục, tôi bị giới hạn chỉ ở một "miền" Python duy nhất cho mỗi quy trình. Khi người dùng thứ hai muốn tính toán dài hạn, tùy chọn duy nhất là quy trình thứ hai. [Điều này khác với GIL. ]

Các biến toàn cầu kích hoạt các API xấu với hiệu suất kém. Đây là một ví dụ trong đó

// foo.cpp
static int evil_1; 
int evil_2; 

void DoStuff[] {
    static int evil_3;
    thread_local int evil_4; 
}

// foo.h
extern int evil_5; 
int evil_6;

struct Foo {
    static int evil_7; 
};
1 khóa một mutex mỗi khi nó tìm nạp một
// foo.cpp
static int evil_1; 
int evil_2; 

void DoStuff[] {
    static int evil_3;
    thread_local int evil_4; 
}

// foo.h
extern int evil_5; 
int evil_6;

struct Foo {
    static int evil_7; 
};
0. Nó gây ra sự chậm lại 500 lần do căng thẳng trong quá trình so sánh chuỗi đa luồng. C/C++
// foo.cpp
static int evil_1; 
int evil_2; 

void DoStuff[] {
    static int evil_3;
    thread_local int evil_4; 
}

// foo.h
extern int evil_5; 
int evil_6;

struct Foo {
    static int evil_7; 
};
1 là một sự ghê tởm của thiết kế API tồi. Nếu nó không bao giờ sử dụng các biến toàn cầu thì nó sẽ bớt tệ hơn nhiều

Đây chỉ là một vài lý do. Chúng còn nhiều nữa. Trong vài năm qua, tôi đã sửa một số lỗi đáng ngạc nhiên mà nguyên nhân gốc rễ là do "các biến toàn cục"

Có một điều để nói rằng các biến toàn cầu là xấu xa. Nói cách khác, việc không sử dụng toàn cầu rõ ràng là tốt

Ví dụ yêu thích của tôi là cuộc nói chuyện GDC năm 2017 có tiêu đề Công nghệ phát lại trong 'Overwatch'. Kill Cam, Trò chơi và Điểm nổi bật

Overwatch là game bắn súng góc nhìn thứ nhất nhiều người chơi. Một tính năng rất được mong đợi trong các trò chơi này là "kill cam". Khi bạn chết, bạn sẽ được phát lại vài giây cuối cùng từ góc nhìn của kẻ giết người. Khi bạn bị bắn sau lưng, bạn có thể thấy nó xảy ra như thế nào

Đây là một tính năng đặc biệt phức tạp. Nó yêu cầu một số hình thức quay ngược thế giới và phát lại nó từ một góc nhìn khác

Mọi thứ trở nên phức tạp hơn khi quá trình phát lại có thể bị gián đoạn nhanh chóng. Người chơi có thể hủy phát lại vì thất vọng. Thậm chí phức tạp hơn, họ có thể được hồi sinh nhờ khả năng của đồng minh. Hồi sinh đặc biệt khó chịu vì nó có nghĩa là trạng thái thế giới phát lại không thể bỏ qua các sự kiện chơi trò chơi "trực tiếp"

Giải pháp của Blizzard cho vấn đề này là thiên tài. Họ tạo ra hai "miền" hoàn toàn rời rạc. "Miền phát lại" được điền khi chết và được hiển thị cho chế độ xem của khách hàng. Trong khi điều này đang xảy ra, "miền trực tiếp" vẫn đang xử lý các bản cập nhật. Trình kết xuất có thể chụp giữa hai bên bất cứ lúc nào

Hỗ trợ điều này yêu cầu loại bỏ tất cả các biến toàn cầu. Các miền phải hoàn toàn độc lập

Điều này thành công đến nỗi họ kết thúc với bốn miền. Trực tiếp, Phát lại, Sảnh chờ và dàn nhạc

Tôi nghĩ rằng giải pháp này là rất mát mẻ. Thật đơn giản và thanh lịch. Và nó không hoạt động nếu bạn có biến toàn cục hoặc biến đơn. Bài thuyết trình dài khoảng 50 phút và tôi thực sự khuyên bạn nên xem toàn bộ nội dung

Có phải các biến toàn cầu luôn xấu và không an toàn?

Ghi nhật ký theo dõi có thể có giá trị toàn cầu. Không hợp lý khi chuyển thông số ghi nhật ký cho mọi chức năng. Ghi nhật ký bình thường Tôi quan tâm nhiều hơn đến hàng rào. Nó có thể có giá trị toàn cầu. Tuy nhiên, việc đăng nhập toàn cầu cũng khiến tôi đau đớn. Vì vậy, tôi không bị thuyết phục

Có những trường hợp khác? . Có lẽ. Tôi chắc rằng mọi người sẽ cho tôi biết trong phần bình luận. Chúng tồn tại, nhưng chúng rất ít và cách xa nhau

Theo ý kiến ​​​​của tôi, các biến toàn cầu là xấu xa và không an toàn và nên tránh. Sử dụng toàn cầu giới thiệu các lỗi, độ phức tạp và các ràng buộc không chính đáng. Tránh toàn cầu ít bị lỗi hơn, đơn giản hơn và linh hoạt hơn

Ngay cả các hệ thống đơn luồng cũng nên tránh toàn cầu. Bằng cách này, bạn có thể hỗ trợ hai hệ thống độc lập trên các luồng khác nhau. Điều này đặc biệt quan trọng trên Linux, nơi các thư viện dùng chung cũng thích chia sẻ toàn cầu hơn

Điều đáng buồn là toàn cầu thậm chí không thêm nhiều giá trị. Họ để bạn lười biếng. Toàn cầu cung cấp một lợi ích nhỏ bé, nhưng đi kèm với một cái giá lớn và dài hạn

Tôi sẽ không đi xa đến mức nói rằng các biến toàn cục không nên được hỗ trợ bởi các ngôn ngữ lập trình. tôi nghĩ về nó. gần rồi. Cuối cùng, tôi nghĩ rằng nó đáng để thoát hiểm. Tuy nhiên, lối thoát hiểm đó nên được đặt trong ngoặc đơn với unsafe_and_evil để không khuyến khích sử dụng và buộc các lập trình viên phải đưa ra quyết định có ý thức

Có lẽ Carbon có thể bị thuyết phục để áp dụng unsafe_and_evil. . ]

Cảm ơn vì đã đọc

Để rõ ràng, biến toàn cục là gì? . Tuy nhiên các khái niệm áp dụng cho bất kỳ ngôn ngữ

// foo.cpp
static int evil_1; 
int evil_2; 

void DoStuff[] {
    static int evil_3;
    thread_local int evil_4; 
}

// foo.h
extern int evil_5; 
int evil_6;

struct Foo {
    static int evil_7; 
};

Tất cả mọi người một trong những khai báo biến đó là ác. Tôi đã không bao gồm mọi hoán vị. Tất cả họ đều xấu

Các hằng số toàn cầu KHÔNG phải là xấu và bạn có thể tự do sử dụng chúng khi thích hợp

// All constant, all fine
const int fine_1; 
constexpr int fine_2; 
constexpr const int fine_3; 

Một cụm từ khác sẽ là "nhà nước toàn cầu có thể thay đổi là xấu xa". "Hằng" có phải là "biến" không? . Các ngôn ngữ khác nhau sử dụng các thuật ngữ khác nhau

Bạn có nên tránh các biến toàn cầu?

Việc sử dụng các biến toàn cục khiến mã được ghép rất chặt chẽ . Sử dụng các biến toàn cầu gây ô nhiễm không gian tên. Điều này có thể dẫn đến việc chỉ định lại giá trị toàn cầu một cách không cần thiết. Thử nghiệm trong các chương trình sử dụng các biến toàn cục có thể là một nỗi đau lớn vì rất khó để tách rời chúng khi thử nghiệm.

Là biến toàn cầu một thực tế xấu?

Các biến toàn cục không cố định là xấu vì giá trị của chúng có thể bị thay đổi bởi bất kỳ hàm nào . Sử dụng biến toàn cục làm giảm tính modul và tính mềm dẻo của chương trình. Không nên sử dụng biến toàn cục trong chương trình. Thay vì sử dụng biến toàn cục, hãy sử dụng biến cục bộ trong chương trình.

Biến toàn cục có tốt trong Python không?

Trong thế giới lập trình, biến toàn cục trong Python có nghĩa là có phạm vi xuyên suốt chương trình, i. e. , một giá trị biến toàn cục có thể truy cập được trong toàn bộ chương trình trừ khi bị che khuất. Biến toàn cục trong Python thường được khai báo ở đầu chương trình .

Hai lý do khiến bạn không nên sử dụng biến toàn cục trong Python là gì?

Chúng khiến bạn khó lập luận hơn về cách thức hoạt động của chương trình vì bất kỳ thứ gì trong mã của bạn đều có thể thay đổi biến đó . Chúng làm cho việc kiểm tra mã của bạn trở nên khó khăn hơn, vì giờ đây mỗi chức năng không chỉ phụ thuộc vào các đối số mà bạn truyền cho nó mà còn phụ thuộc vào một hoặc nhiều biến toàn cục.

Chủ Đề