2008-10-14 35 views
7

Tôi đang lập trình một trang web trong đó người dùng sẽ có một số cài đặt, chẳng hạn như lựa chọn bảng màu, v.v. Tôi rất vui khi lưu trữ chúng dưới dạng tệp văn bản thuần túy và bảo mật không một vấn đề.Lưu trữ cài đặt người dùng đơn giản trong Python

Cách tôi hiện đang thấy là: có một từ điển, trong đó tất cả các khóa là người dùng và giá trị là các từ điển có cài đặt của người dùng trong đó. Ví dụ, userdb ["bob"] ["colour_scheme"] sẽ có giá trị "xanh dương".

Cách tốt nhất để lưu trữ tệp đó là gì? Dọn dẹp từ điển?

Có cách nào tốt hơn để làm những gì tôi đang cố gắng làm không?

Trả lời

7

Sử dụng cPickle trên từ điển sẽ là lựa chọn của tôi. Từ điển là sự phù hợp tự nhiên đối với các loại dữ liệu này, do đó, với các yêu cầu của bạn, tôi không thấy lý do gì để không sử dụng chúng. Điều đó, trừ khi bạn đang suy nghĩ về việc đọc chúng từ các ứng dụng không phải python, trong trường hợp đó bạn sẽ phải sử dụng một định dạng văn bản trung lập ngôn ngữ. Và ngay cả ở đây bạn có thể lấy đi với dưa chua cộng với một công cụ xuất khẩu.

+1

Sự cố với cPickle trong trường hợp này là bạn không thể tải cài đặt cho chỉ một người dùng, bạn phải tải tất cả. có thể cân bằng tốt hơn và nó cũng không kém phần đơn giản để sử dụng. –

+1

Nếu từ điển của bạn bao gồm các đối tượng của riêng bạn (không chỉ là nội trang) thì bạn có thể gặp rắc rối. Trong một phiên bản sửa đổi trong tương lai mã của bạn, bạn có thể thay đổi tên lớp hoặc di chuyển các lớp vào các gói khác. Sau đó, dữ liệu cũ sẽ không tái hợp thành mã mới. – ChrisCantrell

0

Nếu bạn có cơ sở dữ liệu, tôi có thể đề xuất lưu trữ các cài đặt trong cơ sở dữ liệu. Tuy nhiên, có vẻ như các tệp thông thường có thể phù hợp với môi trường của bạn tốt hơn.

Có thể bạn không muốn lưu trữ tất cả cài đặt người dùng trong cùng một tệp, vì bạn có thể gặp sự cố khi truy cập đồng thời vào một tệp đó. Nếu bạn đã lưu trữ cài đặt của từng người dùng dưới dạng từ điển trong tệp được lưu trữ của riêng họ thì họ sẽ có thể hành động độc lập.

Dưa chuột là cách hợp lý để lưu trữ dữ liệu như vậy, nhưng rất tiếc định dạng dữ liệu dưa chuột không nổi tiếng là không thể đọc được. Bạn có thể nên lưu trữ nó dưới dạng repr(dictionary), đây sẽ là định dạng dễ đọc hơn. Để tải lại cài đặt người dùng, hãy sử dụng eval(open("file").read()) hoặc điều gì đó tương tự.

6

Tôi không giải quyết câu hỏi nào là tốt nhất. Nếu bạn muốn xử lý các tệp văn bản, tôi sẽ xem xét ConfigParser -module. Một cách khác bạn có thể thử là simplejson hoặc yaml. Bạn cũng có thể xem xét một bảng db thực sự.

Ví dụ, bạn có thể có một bảng gọi là userattrs, với ba cột:

  • Int user_id
  • Chuỗi ATTRIBUTE_NAME
  • Chuỗi ATTRIBUTE_VALUE

Nếu chỉ có số ít, bạn có thể lưu trữ chúng vào cookie để truy xuất nhanh.

4

Đây là cách đơn giản nhất. Sử dụng các biến đơn giản và import tệp cài đặt.

Gọi file userprefs.py

# a user prefs file 
color = 0x010203 
font = "times new roman" 
position = (12, 13) 
size = (640, 480) 

Trong ứng dụng của bạn, bạn cần phải chắc chắn rằng bạn có thể nhập tập tin này. Bạn có nhiều lựa chọn.

  1. Sử dụng PYTHONPATH. Yêu cầu PYTHONPATH được đặt để bao gồm thư mục có tệp tùy chọn.

    a. Một tham số dòng lệnh rõ ràng để đặt tên tệp (không phải là tốt nhất, nhưng đơn giản)

    b. Một biến môi trường để đặt tên cho tệp.

  2. Mở rộng sys.path để bao gồm thư mục home của người dùng

Ví dụ

import sys 
import os 
sys.path.insert(0,os.path.expanduser("~")) 
import userprefs 
print userprefs.color 
+0

Bạn sẽ không phải có một tệp riêng cho từng người dùng? Điều đó có vẻ như rất nhiều chi phí. –

+0

@Mark Biek: "Những người dùng này sẽ có một số cài đặt," Có vẻ như cài đặt cho mỗi người dùng đối với tôi. Có thể hiểu sai câu hỏi. –

+0

Tôi đã bỏ phiếu vì đây là giải pháp tuyệt vời cho vấn đề của tôi - đó không phải là câu hỏi chính xác. Tôi muốn có tệp cấu hình cho ứng dụng dòng lệnh, đây là trường hợp sử dụng khá khác. –

1

Nếu readablity nhân của configfiles vấn đề một sự thay thế có thể là the ConfigParser module cho phép bạn đọc và ghi .ini như file . Nhưng sau đó bạn bị giới hạn ở một mức làm tổ.

2

Tôi sẽ sử dụng shelve hoặc một cơ sở dữ liệu sqlite nếu tôi sẽ phải lưu trữ các cài đặt này trên hệ thống tệp. Mặc dù, kể từ khi bạn đang xây dựng một trang web bạn có thể sử dụng một số loại cơ sở dữ liệu vậy tại sao không chỉ sử dụng?

0

Có lý do cụ thể nào mà bạn không sử dụng cơ sở dữ liệu cho việc này không? có vẻ như điều bình thường và tự nhiên cần làm - hoặc lưu trữ một loạt các cài đặt trong db được khóa trên id người dùng hoặc một cái gì đó.

Bạn chưa mô tả các mẫu sử dụng của trang web, nhưng chỉ nghĩ đến một trang web chung - nhưng tôi nghĩ rằng việc giữ các cài đặt trong cơ sở dữ liệu sẽ khiến đĩa I/O ít hơn nhiều so với sử dụng tệp.

OTOH, đối với các cài đặt có thể được sử dụng bởi mã phía máy khách, lưu trữ chúng dưới dạng javascript trong tệp tĩnh có thể được lưu vào bộ nhớ cache sẽ rất tiện lợi - với chi phí có nhiều nơi bạn có thể có cài đặt. (Tôi có thể lưu trữ các cài đặt đó trong db và xây dựng lại các tệp tĩnh nếu cần)

0

Tôi đồng ý với câu trả lời về việc sử dụng Từ điển được Pickled. Rất đơn giản và hiệu quả để lưu trữ dữ liệu đơn giản trong cấu trúc Từ điển.

0

Nếu bạn không quan tâm đến việc có thể tự chỉnh sửa tệp và muốn có cách nhanh chóng để tiếp tục tồn tại các đối tượng python, hãy truy cập pickle. Nếu bạn muốn tệp có thể đọc được bởi một người hoặc có thể đọc được bởi một số ứng dụng khác, hãy sử dụng ConfigParser. Nếu bạn cần bất kỳ điều gì phức tạp hơn, hãy sử dụng một số loại cơ sở dữ liệu, có thể là quan hệ (sqlite) hoặc hướng đối tượng (axiom, zodb).

3

Đối với trang web dựa trên cơ sở dữ liệu, tất nhiên, tùy chọn tốt nhất của bạn là bảng db. Tôi giả định rằng bạn không làm điều cơ sở dữ liệu.

Nếu bạn không quan tâm đến các định dạng có thể đọc được, thì pickle là cách đơn giản và dễ hiểu. Tôi cũng đã nghe báo cáo tốt về simplejson.

Nếu khả năng đọc của con người là quan trọng, hai lựa chọn đơn giản thể hiện mình:

Module: Chỉ cần sử dụng một mô-đun. Nếu tất cả những gì bạn cần là một vài hình cầu và không có gì lạ mắt, thì đây là con đường để đi. Nếu bạn thực sự tuyệt vọng, bạn có thể định nghĩa các lớp và các biến lớp để mô phỏng các phần.Nhược điểm ở đây: nếu tệp sẽ được người dùng chỉnh sửa bằng tay, các lỗi có thể khó nắm bắt và gỡ lỗi.

Định dạng INI: Tôi đã sử dụng ConfigObj cho điều này, với khá nhiều thành công. ConfigObj về bản chất là một sự thay thế cho ConfigParser, với sự hỗ trợ cho các phần lồng nhau và nhiều hơn nữa. Theo tùy chọn, bạn có thể xác định các loại hoặc giá trị mong muốn cho một tệp và xác thực nó, cung cấp mạng an toàn (và phản hồi lỗi quan trọng) cho người dùng/quản trị viên.

9

Tôi sẽ sử dụng các mô-đun ConfigParser, trong đó sản xuất một số lượng khá dễ đọc và dễ sử dụng có thể chỉnh sửa ví dụ của bạn:

[bob] 
colour_scheme: blue 
british: yes 
[joe] 
color_scheme: that's 'color', silly! 
british: no

Các mã sau sẽ tạo ra các tập tin cấu hình trên, và sau đó in ra:

import sys 
from ConfigParser import * 

c = ConfigParser() 

c.add_section("bob") 
c.set("bob", "colour_scheme", "blue") 
c.set("bob", "british", str(True)) 

c.add_section("joe") 
c.set("joe", "color_scheme", "that's 'color', silly!") 
c.set("joe", "british", str(False)) 

c.write(sys.stdout) # this outputs the configuration to stdout 
        # you could put a file-handle here instead 

for section in c.sections(): # this is how you read the options back in 
    print section 
    for option in c.options(section): 
      print "\t", option, "=", c.get(section, option) 

print c.get("bob", "british") # To access the "british" attribute for bob directly 

Lưu ý rằng ConfigParser chỉ hỗ trợ chuỗi, vì vậy bạn sẽ phải chuyển đổi như tôi đã nói ở trên cho Booleans. Xem số effbot để biết các thông tin cơ bản.

1

Mô-đun sqlite3 tích hợp có lẽ sẽ đơn giản hơn nhiều so với hầu hết các lựa chọn thay thế và giúp bạn sẵn sàng cập nhật lên một RDBMS đầy đủ nếu bạn muốn hoặc cần.

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