Nó có thể hữu ích trong 'python khai báo'.Ví dụ, ở bên dưới FooDef
và BarDef
là các lớp được sử dụng để xác định một loạt các cấu trúc dữ liệu mà sau đó được sử dụng bởi một số gói làm đầu vào của nó hoặc cấu hình của nó. Điều này cho phép bạn rất linh hoạt trong những gì đầu vào của bạn, và bạn không cần phải viết một trình phân tích cú pháp.
# FooDef, BarDef are classes
Foo_one = FooDef("This one", opt1 = False, valence = 3)
Foo_two = FooDef("The other one", valence = 6, parent = Foo_one)
namelist = []
for i in range(6):
namelist.append("nm%03d"%i)
Foo_other = FooDef("a third one", string_list = namelist)
Bar_thing = BarDef((Foo_one, Foo_two), method = 'depth-first')
Lưu ý rằng tệp cấu hình này sử dụng vòng lặp để tạo danh sách tên là một phần của cấu hình Foo_other
. Vì vậy, ngôn ngữ cấu hình này đi kèm với một 'preprocessor' rất mạnh, với một thư viện thời gian chạy có sẵn. Trong trường hợp bạn muốn tìm kiếm một bản ghi phức tạp hoặc trích xuất mọi thứ từ một tệp zip và giải mã base64, như là một phần của việc tạo cấu hình của bạn (tất nhiên, phương pháp này không được khuyến nghị trong trường hợp đầu vào có thể từ nguồn không tin cậy ...)
các gói phần mềm đọc cấu hình sử dụng giống như sau:
conf_globals = {} # make a namespace
# Give the config file the classes it needs
conf_globals['FooDef']= mypkgconfig.FooDef # both of these are based ...
conf_globals['BarDef']= mypkgconfig.BarDef # ... on .DefBase
fname = "user.conf"
try:
exec open(fname) in conf_globals
except Exception:
...as needed...
# now find all the definitions in there
# (I'm assuming the names they are defined with are
# significant to interpreting the data; so they
# are stored under those keys here).
defs = {}
for nm,val in conf_globals.items():
if isinstance(val,mypkgconfig.DefBase):
defs[nm] = val
Vì vậy, cuối cùng nhận được đến điểm, globals()
là hữu ích, khi sử dụng một gói phần mềm như vậy, nếu bạn muốn đúc một loạt các định nghĩa theo thủ tục:
for idx in range(20):
varname = "Foo_%02d" % i
globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i)
này tương đương với viết ra
Foo_00 = FooDef("one of several", id_code = 1, scale_ratio=1)
Foo_01 = FooDef("one of several", id_code = 2, scale_ratio=2)
Foo_02 = FooDef("one of several", id_code = 3, scale_ratio=4)
... 17 more ...
Một ví dụ về một gói mà có được đầu vào của nó bằng cách thu thập một loạt các định nghĩa từ một mô-đun python là PLY (Python-lex-yacc) http://www.dabeaz.com/ply/ - trong trường hợp đó các đối tượng chủ yếu là các đối tượng hàm, nhưng siêu dữ liệu từ các đối tượng hàm (tên của chúng, các docstrings và thứ tự của định nghĩa) cũng là một phần của đầu vào. Nó không phải là một ví dụ tốt cho việc sử dụng globals()
. Ngoài ra, nó được nhập khẩu bởi 'cấu hình' - sau này là một tập lệnh python bình thường - chứ không phải là cách khác xung quanh.
Tôi đã sử dụng 'python khai báo' trên một số dự án mà tôi đã làm việc và đã có dịp sử dụng globals()
khi viết cấu hình cho những người đó. Bạn chắc chắn có thể tranh luận rằng điều này là do một điểm yếu trong cách cấu hình 'ngôn ngữ' được thiết kế. Sử dụng globals()
theo cách này không tạo ra kết quả rất rõ ràng; chỉ các kết quả có thể dễ duy trì hơn là viết ra hàng tá câu lệnh gần như giống hệt nhau.
Bạn cũng có thể sử dụng nó để cung cấp cho các biến có ý nghĩa trong tập tin cấu hình, theo tên của họ:
# All variables above here starting with Foo_k_ are collected
# in Bar_klist
#
foo_k = [ v for k,v in globals().items() if k.startswith('Foo_k_')]
Bar_klist = BarDef(foo_k , method = "kset")
Phương pháp này có thể hữu ích cho bất kỳ mô-đun python định nghĩa rất nhiều bảng và các cấu trúc, để làm cho việc thêm các mục vào dữ liệu dễ dàng hơn, mà không phải duy trì các tham chiếu.
"Nhưng bạn không bao giờ nên gặp phải vấn đề về việc có hai biến có cùng tên và cần phải sử dụng cả hai biến đó trong cùng một phạm vi". Tôi không thể làm theo suy nghĩ này. Đó là toàn bộ lý do cho các không gian tên riêng biệt, rằng bạn có các biến có cùng tên trong các phạm vi khác nhau. Khi bạn làm việc với hai trong số họ, tên trùng lặp là một điều tự nhiên, nhưng không phải là một vấn đề, như bạn có thể tiền tố chúng. – Michael
Tôi cũng đến từ gia đình C++, vì vậy tôi không chắc chắn về người Python, nhưng theo như tôi có thể nghĩ đến, bạn không nên có một ** toàn cầu ** biến mà không có một tên duy nhất. Chắc chắn sẽ có các biến có cùng tên, trong cùng một phạm vi, đó là câu ngu ngốc từ tôi, nhưng không phải là các hình cầu có cùng tên với các tên địa phương. Đó là khi tôi sử dụng không gian tên cho những người địa phương ... Nhưng không biết, nếu bạn nói như vậy. –
@Mahi: 'globals' có lẽ là một chút gây hiểu lầm. 'globals()' về cơ bản là 'local()' của một module.Python gần nhất đến các globals thực sự toàn cầu cho tất cả chương trình của bạn là ['__builtin__' module] (http://docs.python.org/library/__builtin__.html); bất cứ thứ gì bạn thêm vào * mô đun * đó sẽ có sẵn trong tất cả các không gian tên ở khắp mọi nơi. –