2012-08-06 45 views
14

Hiện đang phân tích cú pháp tệp một cách rộng rãi, tạo một từ điển gồm ~ 400 cặp khóa, giá trị, ít khi được cập nhật. Trước đây đã có một hàm phân tích cú pháp tệp, đã viết nó vào một tệp văn bản theo cú pháp từ điển (ví dụ: dict = {'Adam': 'Room 430', 'Bob': 'Room 404'}) v.v ... và sao chép và dán nó vào một hàm khác có mục đích duy nhất là trả về từ điển được phân tích cú pháp đó.Cách thanh lịch để lưu trữ từ điển vĩnh viễn bằng Python?

Do đó, trong mọi tệp mà tôi sẽ sử dụng từ điển đó, tôi sẽ nhập hàm đó và gán nó vào một biến, giờ là từ điển đó. Tự hỏi liệu có cách nào thanh lịch hơn để thực hiện việc này không liên quan đến việc sao chép và dán mã một cách rõ ràng? Sử dụng một loại cơ sở dữ liệu có vẻ không cần thiết và tệp văn bản đã cho tôi lợi ích của việc xem liệu phân tích cú pháp đã được thực hiện đúng chưa trước khi thêm nó vào hàm. Nhưng tôi đang mở lời đề nghị.

+0

thể trùng lặp: http://stackoverflow.com/questions/7100125/storing-python-dictionaries –

+0

Serialize để json, viết json vào một tập tin, đọc một tập tin, 'json.loads()' sau đó? – favoretti

+0

Xem thêm: [Cách lưu từ điển vào một tệp bằng Python?] (Http://stackoverflow.com/q/19201290/562769) và [Lưu trữ các từ điển Python] (http://stackoverflow.com/q/7100125/562769). –

Trả lời

33

Tại sao không đổ nó vào một tệp JSON, và sau đó tải nó từ đó, nơi bạn cần nó?

import json 

with open('my_dict.json', 'w') as f: 
    json.dump(my_dict, f) 

# elsewhere... 

with open('my_dict.json') as f: 
    my_dict = json.load(f) 

Tải từ JSON khá hiệu quả.

Một tùy chọn khác là sử dụng pickle, nhưng không giống như JSON, các tệp mà tệp tạo ra không thể đọc được do đó bạn sẽ bị mất xác minh hình ảnh bạn thích từ phương pháp cũ của mình.

3

Nếu hiệu quả lưu trữ quan trọng, hãy sử dụng Pickle hoặc CPickle (để đạt được hiệu suất thực thi). Như Amber đã chỉ ra, bạn cũng có thể đổ/tải thông qua Json. Nó sẽ là con người có thể đọc được, nhưng có nhiều đĩa hơn.

4

JSON có lẽ là cách phù hợp để thực hiện trong nhiều trường hợp; nhưng có thể có một sự thay thế. Có vẻ như chìa khóa của bạn và giá trị của bạn luôn là chuỗi, đúng không? Bạn có thể xem xét sử dụng dbm/anydbm. Đây là "cơ sở dữ liệu" nhưng chúng hoạt động gần giống như từ điển. Chúng tuyệt vời cho sự kiên trì dữ liệu giá rẻ.

>>> import anydbm 
>>> dict_of_strings = anydbm.open('data', 'c') 
>>> dict_of_strings['foo'] = 'bar' 
>>> dict_of_strings.close() 
>>> dict_of_strings = anydbm.open('data') 
>>> dict_of_strings['foo'] 
'bar' 
4

Nếu các phím là tất cả các chuỗi, bạn có thể sử dụng các mô-đun shelve

Một shelf là một, từ điển giống như đối tượng dai dẳng. Sự khác biệt với cơ sở dữ liệu “dbm” là các giá trị (không phải là khóa!) Trong một giá có thể là về cơ bản các đối tượng Python tùy ý - bất kỳ thứ gì mà mô-đun pickle có thể xử lý. Điều này bao gồm hầu hết các phiên bản lớp, kiểu dữ liệu đệ quy, và các đối tượng chứa nhiều đối tượng phụ được chia sẻ. Các phím là chuỗi thông thường.

json sẽ là một lựa chọn tốt nếu bạn cần phải sử dụng các dữ liệu từ các ngôn ngữ khác

+0

Tôi cũng đọc những thứ khiến tôi tin rằng các tập tin 'shelve' không tương thích với nền tảng vì cơ sở dữ liệu cơ bản được sử dụng có thể khác nhau (và không có cách nào tốt để kiểm soát nó). – martineau

2

tôi đề nghị bạn xem xét việc sử dụng các mô-đun shelve kể từ khi cấu trúc dữ liệu của bạn là một ánh xạ. Đó là tôi answer cho một câu hỏi tương tự với tựa đề If I want to build a custom database, how could I? Ngoài ra còn có một chút mã mẫu trong một answer của tôi thúc đẩy việc sử dụng nó cho câu hỏi How to get a object database?

ActiveState có một đánh giá cao PersistentDict recipe mà hỗ trợ csv, json, và sản lượng dưa định dạng tệp. Nó khá nhanh vì cả ba định dạng này đều được triển khai trong C (mặc dù bản thân công thức là Python thuần túy), vì vậy thực tế là nó đọc toàn bộ tệp vào bộ nhớ khi nó được mở có thể chấp nhận được.

0

theo hướng JSON cũng có tên gọi là simpleJSON. Lần đầu tiên của tôi bằng cách sử dụng json trong python thư viện json didnt làm việc cho tôi/tôi couldnt con số nó ra. simpleJSON được ... dễ dàng hơn để sử dụng

0

JSON (hoặc YAML, hoặc bất kỳ) serialization có lẽ tốt hơn, nhưng nếu bạn đã viết từ điển vào một tệp văn bản trong cú pháp python, hoàn thành với một tên biến ràng buộc, bạn có thể chỉ cần viết nó vào một tập tin .py thay thế. Sau đó, tệp python đó sẽ có thể nhập và có thể sử dụng được. Không cần cho phương thức "trả về một từ điển", vì bạn có thể trực tiếp sử dụng nó như một tệp toàn cục trong tệp đó. ví dụ.

# generated.py 
please_dont_use_dict_as_a_variable_name = {'Adam': 'Room 430', 'Bob': 'Room 404'} 

hơn:

# manually_copied.py 
def get_dict(): 
    return {'Adam': 'Room 430', 'Bob': 'Room 404'} 

Sự khác biệt duy nhất là manually_copied.get_dict cung cấp cho bạn một bản sao tươi của từ điển mọi thời gian, trong khi generated.please_dont_use_dict_as_a_variable_name [1] là một đối tượng chia sẻ duy nhất. Điều này có thể quan trọng nếu bạn đang sửa đổi từ điển trong chương trình của bạn sau khi truy xuất nó, nhưng bạn luôn có thể sử dụng copy.copy hoặc copy.deepcopy để tạo bản sao mới nếu bạn cần sửa đổi một bản sao độc lập với những người khác.


[1] dict, list, str, int, map, vv thường được coi là tên biến xấu. Lý do là chúng đã được định nghĩa là được xây dựng sẵn và được sử dụng rất phổ biến. Vì vậy, nếu bạn cho một cái gì đó một cái tên như vậy, ít nhất nó sẽ gây ra nhận thức-dissonance cho những người đọc mã của bạn (bao gồm cả bạn sau khi bạn đã đi một lúc) vì họ phải ghi nhớ rằng "dict doesn ' t có nghĩa là những gì nó thường làm ở đây ". Nó cũng khá có khả năng là tại một số điểm bạn sẽ nhận được một lỗi đáng lo ngại để báo cáo rằng dict đối tượng không thể gọi được (hoặc một cái gì đó), bởi vì một số đoạn mã đang cố gắng sử dụng loạidict, nhưng nhận được đối tượng từ điển bạn đã gắn với tên dict thay thế.

14

Tại sao lại gây rối với tất cả các phương pháp tuần tự hóa này? Nó đã được ghi vào một tập tin như một dict Python (mặc dù với tên không may 'dict'). Thay đổi chương trình của bạn để ghi dữ liệu với tên biến tốt hơn - có thể là 'dữ liệu' hoặc 'danh mục' và lưu tệp dưới dạng tệp Python, nói data.py. Sau đó, bạn chỉ có thể nhập dữ liệu trực tiếp vào thời gian chạy mà không cần sao chép/dán vụng về hoặc JSON/shelve/etc. phân tích cú pháp:

from data import catalog 
+1

+1: Đây là câu trả lời hay nhất cho câu hỏi của OP, IMHO. – martineau

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