2010-09-23 40 views
5

Làm cách nào để chuyển từ điển sang tập lệnh python từ tập lệnh python khác trên dòng lệnh? Tôi sử dụng subprocess để gọi kịch bản thứ hai.Chuyển từ điển sang tập lệnh Python thông qua dòng lệnh

Các tùy chọn tôi đã đến là:
I) Xây dựng mô-đun để phân tích cú pháp từ điển từ chuỗi (sâu hơn tôi mong đợi).
II) Sử dụng tệp tạm thời để viết dưa và chuyển tên tệp làm đối số
III) Không cho phép từ điển, nhưng xử lý cặp khóa/giá trị (đó là "prog.py keya valuea keyb valub")

Giải pháp không nhất thiết phải thân thiện với người dùng, nhưng không cần phải thân thiện với chương trình. Chương trình thứ hai phải được chạy như một quá trình riêng biệt, do các vấn đề về bảo mật và tài nguyên.

Trả lời

6

Ngoài pickle, tùy chọn khác là ast.literal_eval, nếu từ điển của bạn chỉ chứa các nguyên thủy gốc Python.

>>> d = {3: 9, 'apple': 'orange'} 
>>> s = str(d) 
>>> s 
"{3: 9, 'apple': 'orange'}" 
>>> import ast 
>>> x = ast.literal_eval(s) 
>>> x 
{3: 9, 'apple': 'orange'} 
+0

Đây chính xác là những gì tôi đang tìm kiếm –

6

Nếu bạn không cần cấu trúc dữ liệu quá phức tạp, tôi có thể khuyên bạn nên simplejson? Nó có sẵn như là một mô-đun tích hợp (được gọi là json) trong Python 2.6 trở lên.

+0

Yeah, bạn có thể vượt qua json điển serialized bằng cách viết nó vào stdin của thứ hai kịch bản. – Epeli

+0

+1 vì JSON đơn giản, hiệu quả và gần giống với cấu trúc 'dict' của Python. – jathanism

+0

+1 bởi vì điều này là hoàn hảo, mặc dù câu trả lời của FoggleBird là hoàn hảo hơn, và tôi không thể nói chuyện với ông chủ vào bất cứ điều gì mà đề với javascript –

8

Bạn đã xem mô-đun pickle để chuyển dữ liệu qua stdout/stdin?

Ví dụ:

knights.py:

import pickle 
import sys 

desires = {'say': 'ni', 'obtain': 'shrubbery'} 
pickle.dump(desires, sys.stdout) 

roundtable.py:

import pickle 
import sys 

knightsRequest = pickle.load(sys.stdin) 
for req in knightsRequest: 
    print "The knights %s %s." % (req, knightsRequest[req]) 

Cách sử dụng và sản lượng:

$ python knights.py | python roundtable.py 
The knights say ni. 
The knights obtain shrubbery. 
+0

Không phải là một ý tưởng tồi! – jathanism

0

Chỉ cần in từ điển trong một python script

print("dict=" + str(dict)) 

và sử dụng nó như

(python script1.py; cat script2.py) | python - 

và bây giờ bạn sẽ có quyền truy cập có thể từ điển thông qua biến toàn cầu 'dict' trong kịch bản lệnh python thứ hai.

2

Nếu nội dung trong từ điển (cả khóa và giá trị) có thể được biểu diễn dưới dạng chuỗi, bạn có thể chuyển nó làm đối số chuỗi cho tập lệnh thứ hai có thể tạo lại.

d = {'a':1,'b':2} 

d == eval(repr(d), None) 

>>>True 

Edit: Dưới đây là một ví dụ hơi tham gia nhiều hơn cho thấy việc sử dụng nó với một lớp tùy chỉnh đơn giản:

class MyClass: 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
    def __repr__(self): 
     return 'MyClass(%r, %r)' % (self.a, self.b) 
    def __eq__(self, other): 
     return (self.a == other.a) and (self.b == other.b) 

d = {'foo':42, 'bar': MyClass(17,'astring') } 

print 'd:', d 
print 'repr(d):', repr(d) 
print "d == eval(repr(d), {'MyClass':MyClass})?:", \ 
     d == eval(repr(d), {'MyClass':MyClass}) 

# outputs: 
# d: {'foo': 42, 'bar': MyClass(17, 'astring')} 
# repr(d): {'foo': 42, 'bar': MyClass(17, 'astring')} 
# d == eval(repr(d), {'MyClass':MyClass})?: True 
+0

'ast.literal_eval' là cách an toàn và chính xác để thực hiện việc này. – FogleBird

+0

'ast.literal_eval()' có thể quá hạn chế. Thay vì None, có thể chuyển 'eval()' một đối số thứ hai thay vì một từ điển ánh xạ các tên lớp tùy chỉnh cho các lớp tùy chỉnh tương ứng, khi được cung cấp, sẽ cho phép các cá thể của chúng cũng được tái tạo thêm vào chuỗi, số , tuples, lists, dicts, booleans, và None loại giá trị mà 'ast.literal_eval()' hỗ trợ. – martineau

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