2016-03-26 10 views
7

Tôi có cấu hình os.environ với các giá trị mặc định (bao gồm 90% nhu cầu của tôi). Tôi có một gói ứng dụng đặc biệt, ví dụ, gọi là SALOME, không cung cấp cài đặt gói vào môi trường hệ thống và cố gắng tự chứa, nó cũng yêu cầu sử dụng các công nghệ cũ đặc biệt dựa vào các biến môi trường do đó sys.pathPYTHONPATH không điều duy nhất nó cần. Tôi có thể nhận được tất cả các biến cần thiết khi nó bắt đầu gọi os.environ bên trong một môi trường mà nó tạo ra. Sau đó tôi có thể tuần tự hóa từ đó os.environ từ điển.Làm thế nào để thực hiện os.environ tham gia vào python?

Tôi tự hỏi làm thế nào để áp dụng một hợp nhất của os.environ Tôi có trên hệ thống hiện đang chạy của tôi với một tôi thu được bằng cách tuần tự hóa?

+2

Bạn có nghĩa là 'os.environ.update (deserialized_environment)'? – mgilson

+0

@mqilson: có điều gì đó tương tự. Không xóa - chỉ chèn và bổ sung. – DuckQueen

+1

@DuckQueen và tại sao giải pháp chính xác của mgilson không hiệu quả đối với bạn? 'os.environ' là một dict, một đối tượng khác là dict và' dict.update' sẽ hoạt động giống như bạn đã giải thích - dữ liệu dict sẽ bị ghi đè bởi dữ liệu từ đối số 'update()'. Các khóa không xung đột sẽ bị giữ nguyên. –

Trả lời

5

Giả sử bạn đã làm một cái gì đó như sau để serialize môi trường:

import json 
import os 

with open('environ.json', 'w') as f: 
    json.dump(dict(**os.environ), f) 

Bây giờ bạn có thể đọc những người trở lại như thế này (trong một chương trình khác)

import json 
import os 

with open('environ.json', 'r') as f: 
    os.environ.update(json.load(f)) 

này sẽ chỉ làm tăng thêm hoặc thay đổi các biến môi trường hiện tại để phù hợp với các biến được lưu, nhưng mọi biến bổ sung sẽ vẫn còn.

Nếu bạn muốn cập nhật chỉ biến cụ thể bằng cách thêm chúng (vì vậy ví dụ để thêm các đường dẫn phụ), bạn có thể làm điều đó một cách rõ ràng:

with open('environ.json', 'r') as f: 
    loadedenv = json.load(f) 

pathvars = ['PATH', 'PYTHONPATH'] 

for p in pathvars: 
    os.environ[p] += ':' + loadedenv[p] 
+0

Nó có thể nối hoặc thay thế các chuỗi đã tồn tại (ví dụ: đường dẫn) không? – DuckQueen

+0

Nó sẽ thay thế các giá trị hiện tại bằng các giá trị mới. – chthonicdaemon

+0

@DuckQueen Để hợp nhất các đường dẫn, bạn cần phải suy nghĩ về cách - các giá trị được nạp sẽ được thêm vào trước hoặc sau các giá trị hiện có, có nên có quá trình hợp nhất không? Tôi đã thêm một phương thức chỉ thêm các giá trị mới vào cuối bằng dấu phân cách ':'. – chthonicdaemon

1

Nếu bạn muốn có nhiều giá trị cho một cuốn từ điển đó từ điển python chuẩn không cung cấp hơn bạn có thể sử dụng

werkzeug.datastructures.MultiDict 
os.environ = MultiDict([('Key1', 'First Value'), ('Key1', 'Second Value')]) 

Bản cập nhật cũng sẽ hoạt động theo cách tương tự như tôi đã đề cập bên dưới.

Nếu bạn không muốn giữ lại các giá trị khóa cũ trước khi hợp nhất với từ điển mới, bạn có thể thực hiện các thao tác sau.

Vì os.environ là một từ điển mà bạn đã có trong bộ nhớ, dict khác là từ bạn đang đọc sẽ cần phải được chuyển đổi thành json. Tôi thường sử dụng ujson vì nó rất nhanh.

os.environ.update(new_dict) 

Nếu bạn muốn lưu json u có thể đổ nó vào một tệp.

import ujson 

with open('data.json', 'w') as file: 
    ujson.dump(dict(**os.environ), file) 

nếu bạn muốn đọc tệp và cập nhật từ điển os.environ mà bạn có thể sử dụng.

with open('environ.json', 'r') as f: 
    os.environ.update(ujson.load(f)) 
+0

Đặt 'os.environ' theo cách này không hoạt động, vì' os.environ' không phải là "chỉ" một từ điển - nó có các phương thức thực sự thiết lập các biến môi trường cho con của quá trình . Thử nghiệm bằng cách sử dụng 'os.system (echo $ Key1)' và bạn sẽ thấy nó không được thiết lập. – chthonicdaemon

3

Bạn có thể sử dụng gói environs để đạt được xuất khẩu từ điển os.environ. Nó có dumper/loader sẵn có để xuất khẩu nhập các biến môi trường.

from environs import Env 

env = Env() 
# reading an environment variable 
gh_user = env('GITHUB_USER') # => 'sloria' 
secret = env('SECRET') # => raises error if not set 

# casting 
api_key = env.str('API_KEY') # => '123abc' 
date = env.date('SHIP_DATE') # => datetime.date(1984, 6, 25) 

# serialize to a dictionary of simple types (numbers and strings) 
env.dump() 
# { 'API_KEY': '123abc', 
# 'GITHUB_USER': 'sloria',  
# 'SECRET': 'AASJI93WSJD93DWW3X0912NS2', 
# 'SHIP_DATE': '1984-06-25'}} 
Các vấn đề liên quan