如何修改模块中的变量和实例并在运行时在python中保存
Posted
技术标签:
【中文标题】如何修改模块中的变量和实例并在运行时在python中保存【英文标题】:how to modify variables and instances in modules and save it at runtime in python 【发布时间】:2018-04-05 02:02:11 【问题描述】:我有main.py
,header.py
和var.py
header.py
import var
class table():
def __init__(self, name):
self.name = name
var.py
month = "jen"
table = "" # tried to make empty container which can save table instance but don't know how
main.py
import header
import var
var.table = header.table(var.month)
var.month = "feb"
在这一切之后,我的意思是在这个程序结束之后。我希望 var.table
和 var.month
被修改并保存在 var.py
中。
在 python 中处理引用实在是太混乱了。
我想念 C 和指针。
【问题讨论】:
如果要在程序结束后保存数据,请使用数据文件。 Possible duplicate. 你为什么想念 C 和指针?从 C 中修改 C 源文件不仅比在 Python 中修改 C 源文件更难,而且更无用…… @user202729 这绝对是一个 dup,但肯定有一个问题比 repr/literal_eval 和“不要使用 pickle,但这里是如何使用 pickle”的答案更好...... 还有this one,但这基本上是一场泡菜与莳萝的较量,没有提及 JSON、YAML、CSV、cfg/ini/rc,... 【参考方案1】:当您的程序结束时,您的所有值都会丢失 - 除非您先保存它们,然后在下次运行时加载它们。有多种不同的方法可以做到这一点;你想要哪一个取决于你拥有什么样的数据以及你正在用它做什么。
您永远不想做的一件事是将任意对象打印到文件中,然后尝试弄清楚以后如何解析它们。如果您的任何问题的答案是ast.literal_eval
,则说明您保存错误。
要考虑的一件重要事情是何时保存。如果有人使用 ^C 退出了您的程序,而您只在干净关闭时保存,那么您的所有更改都将消失。
Numpy/熊猫
Numpy 和 Pandas 有自己的内置函数来保存数据。请参阅Numpy docs 和Pandas docs 了解所有选项,但基本选择是:
文本(例如,np.savetxt
):便携式格式,可在电子表格中编辑。
二进制(例如,np.save
):小文件,快速保存和加载。
Pickle(见下文,还包括内置函数):可以使用任意 Python 对象保存数组。
HDF5。如果您需要 HDF5 或 NetCDF,您可能已经知道自己需要它。
字符串列表
如果您只有一个单行字符串列表,您只需将它们写入文件并逐行读取。很难变得更简单,而且它显然是人类可读的。
如果您需要每个值的短名称,或者需要单独的部分,但您的值仍然都是简单的字符串,您可能需要查看 configparser
以获取 CFG/INI 文件。但是,一旦您变得比这更复杂,请寻找不同的格式。
Python 源码
如果您不需要保存任何内容,只加载数据(您的用户可能想要编辑的数据),您可以将 Python 本身用作一种格式——您可以使用 import
的模块或您的脚本文件exec
。这当然是非常危险的,但是对于只有在计算机上已经拥有您的完整源代码的人才能编辑的配置文件,这可能不是问题。
JSON 和朋友
JSON 可以将单个字典或列表保存到文件中并重新加载。 JSON 是built into the Python standard library,大多数其他语言也可以加载和保存它。 JSON 文件是人工可编辑的,但并不美观。
JSON 字典和列表可以是嵌套结构,内部有其他字典和列表,也可以包含字符串、浮点数、布尔值和无,但仅此而已。您可以使用其他类型的转换器扩展 json
库,但这需要一些工作。
YAML (几乎)是 JSON 的超集,更易于扩展,并且允许更漂亮的人工可编辑文件。它在标准库中没有内置支持,但 PyPI 上有许多可靠的库,例如 ruamel.yaml
。
JSON 和 YAML 都只能为每个文件保存一个字典或列表。 (该库将允许您保存多个对象,但您将无法将它们加载回来,所以要小心。)解决此问题的最简单方法是创建一个大字典或列表,其中包含所有数据。但是JSON Lines 允许您将多个 JSON 字典保存在一个文件中,但代价是人类可读性。你可以通过for line in file: obj = json.loads(obj)
加载它,如果你知道你在做什么,你可以只用标准库保存它,但你也可以找到像json-lines
这样的第三方库来为你做。
键值存储
如果您要存储的内容适合 dict,但您希望始终将其保存在磁盘上而不是显式保存和加载,则需要键值存储。
dbm
是一种旧的但仍然有效的格式,只要你的键和值都是小字符串并且你没有大量的字符串。 Python 使dbm
看起来像dict
,因此您根本不需要更改大部分代码。
shelve
扩展 dbm
让您可以保存任意值而不仅仅是字符串。它通过使用 Pickle(见下文)来做到这一点,这意味着它具有相同的安全问题,而且速度也可能很慢。
更强大的键值对存储(和相关的东西)通常被称为 NoSQL 数据库。现在有很多。 Redis 是流行的选择之一。还有更多需要学习,但值得。
CSV
CSV 代表“逗号分隔值”,尽管有使用空格或其他字符的变体。 CSV 是 built into the standard library。
当您拥有一个包含相同字段的对象列表时,这是一种很好的格式,只要所有成员都是字符串或数字。但不要试图超越它。
CSV 文件几乎无法像文本一样进行人工编辑,但可以在 Excel 或 Google 表格等电子表格程序中非常轻松地进行编辑。
泡菜
Pickle 旨在保存和加载几乎所有内容。如果您正在阅读用户提供的任意 pickle 文件,这可能很危险,但它也非常方便。 Pickle 实际上不能完全保存和加载所有内容,除非您做大量工作来为您的某些类型添加支持,但是有一个名为 dill
的第三方库可以进一步扩展支持。
Pickle 文件根本不可读,仅与 Python 兼容,有时甚至与旧版本的 Python 不兼容。
SQL
最后,您始终可以构建一个完整的关系数据库。这和听起来一样可怕。
Python 在标准库中内置了一个名为 sqlite3
的数据库。
如果这看起来太复杂,您可能需要考虑SQLAlchemy,它可以让您存储和查询数据,而无需学习 SQL 语言。或者,如果您四处搜索,有许多更高级的 ORM 和库,可让您直接针对数据库运行自定义列表推导,等等。
其他格式
对于数据文件,还有很多其他标准; a few even come with support in the standard library。它们对于特殊情况很有用——plist 文件与 Apple 在 macOS 和 ios 上使用的偏好匹配; netrc 文件是一种历史悠久的存储服务器登录列表的方法;如果您有一台只能穿越到 2000 年的时光机,那么 XML 是完美的;等等。但通常情况下,您最好使用上面提到的一种常见格式。
【讨论】:
以上是关于如何修改模块中的变量和实例并在运行时在python中保存的主要内容,如果未能解决你的问题,请参考以下文章