如何在python中修改模块中的变量和实例并在运行时将其保存

2022-03-01 00:00:00 python module runtime

问题描述

我有main.pyheader.pyvar.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.tablevar.month被修改并保存在var.py中。

在python中处理引用非常混乱。

我想念C&;指针。


解决方案

当您的程序结束时,您的所有值都将丢失-除非您先保存它们,然后在下一次运行时加载它们。执行此操作有多种不同的方法;您需要哪种方法取决于您拥有什么类型的数据以及您正在对其执行什么操作。

有一件事您永远不想做,那就是将任意对象打印到文件中,然后尝试稍后如何解析它们。如果您的任何问题的答案是ast.literal_eval,则您保存的内容是错误的。

需要考虑的一件重要事情是何时储蓄。如果有人使用^C退出您的程序,而您仅在完全关机时保存,则您所做的所有更改都将丢失。

块/ pandas

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字典和列表可以与其他字典和列表嵌套在一起,还可以包含字符串、浮点数、布尔值和NONE,但不能包含其他内容。您可以使用其他类型的转换器来扩展json库,但这需要一些工作。

YAML(几乎)是更容易扩展的JSON超集,并且允许更漂亮的人类可编辑文件。它在标准库中没有内置支持,但是在PyPI上有很多实心库,比如ruamel.yaml

JSON和YAML每个文件只能保存一个词典或列表。(该库将允许您保存多个对象,但您将无法重新加载它们,因此要小心。)解决这个问题最简单的方法是创建一个包含所有数据的大字典或列表。但是JSON Lines允许您将多个JSON字典保存在一个文件中,代价是人类的可读性。您可以通过for line in file: obj = json.loads(obj)加载它,如果您知道自己在做什么,可以只用标准库保存它,但是您也可以找到像json-lines这样的第三方库来为您做这件事。

键值存储

如果要存储的内容适合字典,但希望将其始终保存在磁盘上,而不是显式保存和加载,则需要键值存储。

dbm是一种旧的但仍然有效的格式,只要您的键和值都是小巧的字符串,并且没有太多。Python使dbm看起来像dict,因此您根本不需要更改大部分代码。

shelve扩展了dbm,使您可以保存任意值,而不仅仅是字符串。它通过使用Pickle(见下文)来实现这一点,这意味着它有相同的安全问题,而且速度也可能很慢。

功能更强大的键值存储(及相关内容)通常称为NoSQL数据库。现在有很多,Redis是热门选择之一。还有更多东西需要学习,但这可能是值得的。

CSV

CSV代表"逗号分隔值",尽管也有使用空格或其他字符的变体。CSV为built into the standard library。

当您有一个包含相同字段的对象列表时,只要所有成员都是字符串或数字,这就是一种很好的格式。但不要试图超出这个范围。

CSV文件几乎无法编辑为文本,但在Excel或Google Sheets等电子表格程序中可以非常轻松地编辑它们。

泡菜

Pickle旨在保存和加载几乎任何内容。如果您正在读取用户提供的任意PICLE文件,这可能会很危险,但也可能非常方便。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是完美的;等等。但通常情况下,使用上面提到的常用格式之一会更好。

相关文章