如何在一个文件中存储多个变量,并从另一个文件中访问这些变量?

时间:2022-03-09 16:02:14

I want to create a 'mini-database'. I want to have one file with lots of variables, and be able to take those variables from the file, while also being able to add variables to the file? For example, lets suppose this is the 'mini-db':

我想创建一个“迷你数据库”。我想要一个有很多变量的文件,并且能够从文件中取出这些变量,同时也能够向文件中添加变量?例如,假设这是“迷你db”:

hello = ['a', 'b', 'c']
world = ['d', 'e', 'f']
foo = ['g', 'h', 'i']

and from a different file, I would like to say something like:

在另一个文件中,我想说:

print MiniDB.hello[0]

So basically access the variable. Also, I would need to write variables INTO the file. so something like this:

基本上就是访问变量。此外,我还需要将变量写入文件中。所以这样的:

MiniDB.bar = ['j', 'k', 'l']

How can I do this?

我该怎么做呢?

2 个解决方案

#1


3  

shelve is the easiest way to do this. Mind the concurrency restrictions though.

搁置是最简单的方法。但是请注意并发限制。

#2


0  

This may not be what you are looking for, but this class allows storing program settings. You load it with default settings that represent the variables you need and embed dictionaries to generate namespaces. It is not perfect, but tries to allow multiple database definitions to coexist with each other while ensuring data types do not change. It has a limited field of usage but may act as the solution you require.

这可能不是您想要的,但是这个类允许存储程序设置。使用表示所需变量的默认设置加载它,并嵌入字典以生成名称空间。它并不完美,但试图允许多个数据库定义共存,同时确保数据类型不更改。它的使用范围有限,但可以作为您需要的解决方案。

import copy
import pprint
import pickle

################################################################################

class _Interface:

    def __init__(self, default, database=None):
        self.__default = default
        if database is None:
            self.__database = copy.deepcopy(default)
        else:
            self.__database = database

    def __repr__(self):
        return pprint.pformat(self.__database)

    def __getattr__(self, name):
        attr = self.__default[name]
        if isinstance(attr, dict):
            return _Interface(attr, self.__database[name])
        raise AttributeError(name)

    def __setattr__(self, name, value):
        if name in {'_Interface__default', '_Interface__database'}:
            super().__setattr__(name, value)
        else:
            raise AttributeError(name)

    def __getitem__(self, name):
        item = self.__default[name]
        if isinstance(item, dict):
            raise KeyError(name)
        return self.__database[name]

    def __setitem__(self, name, value):
        item = self.__default[name]
        if isinstance(value, type(item)):
            self.__database[name] = value
        else:
            raise TypeError(type(value))

################################################################################

class Registry(_Interface):

    @property
    def __database(self):
        return self._Interface__database

    def load(self, path):
        with open(path, 'rb') as file:
            data = pickle.load(file)
        self.__merge(data, self.__database)

    @classmethod
    def __merge(cls, source, sink):
        for key, value in source.items():
            if key not in sink:
                sink[key] = value
            elif isinstance(value, type(sink[key])):
                if isinstance(value, dict):
                    cls.__merge(value, sink[key])
                else:
                    sink[key] = value

    def save(self, path):
        with open(path, 'wb') as file:
            pickle.dump(self.__database, file)

################################################################################

file1 = Registry({'hello': ['a', 'b', 'c'],
                  'world': ['d', 'e', 'f'],
                  'foo': ['g', 'h', 'i'],
                  'namespace': {'j': 0,
                                'k': 1,
                                'm': '2',
                                'n': '3'}})

file2 = Registry({'hello': ['a', 'b', 'c'],
                  'world': ['d', 'e', 'f'],
                  'foo': ['g', 'h', 'i'],
                  'namespace': {'j': '4',
                                'k': '5',
                                'm': '6',
                                'n': '7'},
                  'bar': []})

file1['hello'][0] = 'z'
file1.save('mini.db')
file2.load('mini.db')
file2['bar'].extend(['j', 'k', 'l'])

print(file2)
print(file2.namespace['k'])
print(file2.namespace['m'])

#1


3  

shelve is the easiest way to do this. Mind the concurrency restrictions though.

搁置是最简单的方法。但是请注意并发限制。

#2


0  

This may not be what you are looking for, but this class allows storing program settings. You load it with default settings that represent the variables you need and embed dictionaries to generate namespaces. It is not perfect, but tries to allow multiple database definitions to coexist with each other while ensuring data types do not change. It has a limited field of usage but may act as the solution you require.

这可能不是您想要的,但是这个类允许存储程序设置。使用表示所需变量的默认设置加载它,并嵌入字典以生成名称空间。它并不完美,但试图允许多个数据库定义共存,同时确保数据类型不更改。它的使用范围有限,但可以作为您需要的解决方案。

import copy
import pprint
import pickle

################################################################################

class _Interface:

    def __init__(self, default, database=None):
        self.__default = default
        if database is None:
            self.__database = copy.deepcopy(default)
        else:
            self.__database = database

    def __repr__(self):
        return pprint.pformat(self.__database)

    def __getattr__(self, name):
        attr = self.__default[name]
        if isinstance(attr, dict):
            return _Interface(attr, self.__database[name])
        raise AttributeError(name)

    def __setattr__(self, name, value):
        if name in {'_Interface__default', '_Interface__database'}:
            super().__setattr__(name, value)
        else:
            raise AttributeError(name)

    def __getitem__(self, name):
        item = self.__default[name]
        if isinstance(item, dict):
            raise KeyError(name)
        return self.__database[name]

    def __setitem__(self, name, value):
        item = self.__default[name]
        if isinstance(value, type(item)):
            self.__database[name] = value
        else:
            raise TypeError(type(value))

################################################################################

class Registry(_Interface):

    @property
    def __database(self):
        return self._Interface__database

    def load(self, path):
        with open(path, 'rb') as file:
            data = pickle.load(file)
        self.__merge(data, self.__database)

    @classmethod
    def __merge(cls, source, sink):
        for key, value in source.items():
            if key not in sink:
                sink[key] = value
            elif isinstance(value, type(sink[key])):
                if isinstance(value, dict):
                    cls.__merge(value, sink[key])
                else:
                    sink[key] = value

    def save(self, path):
        with open(path, 'wb') as file:
            pickle.dump(self.__database, file)

################################################################################

file1 = Registry({'hello': ['a', 'b', 'c'],
                  'world': ['d', 'e', 'f'],
                  'foo': ['g', 'h', 'i'],
                  'namespace': {'j': 0,
                                'k': 1,
                                'm': '2',
                                'n': '3'}})

file2 = Registry({'hello': ['a', 'b', 'c'],
                  'world': ['d', 'e', 'f'],
                  'foo': ['g', 'h', 'i'],
                  'namespace': {'j': '4',
                                'k': '5',
                                'm': '6',
                                'n': '7'},
                  'bar': []})

file1['hello'][0] = 'z'
file1.save('mini.db')
file2.load('mini.db')
file2['bar'].extend(['j', 'k', 'l'])

print(file2)
print(file2.namespace['k'])
print(file2.namespace['m'])