如何根据用户输入更新和保存 python 脚本(仅变量,无逻辑)?
How to update and save a python script (variables only, no logic) based on user input?
我有一个脚本,还有另一个 Python 文件 mappings.py
,其中包含一堆 dicts
和 tuples-of-tuples
)。其中每一个都在第 0 天填充了 Name 和 Age 值对映射的基线。这些又被添加为参考电子表格的行。
在任何给定的一天,将从新一天的电子表格中读取数据。如果任何记录已经在映射字典或元组之一中,则数据将写入相应的行。
挑战如下:在任何给定的一天,如果输入电子表格中的一行 在 mappings.py
中还没有条目 ,我想:
- 提示用户为给定的姓名指定年龄值
- 以某种方式将这个 Name:Age 对添加到 mappings.py 中适当的字典或元组中,这样在随后的日子里,如果脚本再次遇到该名称,它已经 "knows" 关于它.
所以问题是:我如何追加到文件中的给定数据结构,而不是在内存中,而是在实际文件本身中?因此,如果有问题的字典称为 mydict
,并且我要添加一个新的 Name:Age 对,我可以在内存中做:
mappings.py.mydict[$newName] = [$newAge]
但是我如何实际更新文件,以便使用这个新数据进行保存?最终用户不想直接打开 mappings.py
,因此我将显示一些弹出窗口以接收用户指定的对。然后我想知道如何最好地保存这对。
如果 mappings.py 不需要用户可读,请使用常规字典并将 -load\save 作为 pickle
(参见相关问题)
使用 pickle(或 Python 2 中的 cPickle,因为它比普通 pickle 快得多)的常用方法是
- 从 pickle 文件中解开你的数据结构
- 更新程序中的数据结构
- pickle 更新后的结构,覆盖原始 pickle 文件,可能会保存该原始文件的备份。
酸洗过程相当快,因此除非您要酸洗数百万对(姓名、年龄),否则该策略应该足够了。
将数据附加到 pickle 文件中的单个项目是不切实际的。如果您使用人类可读的 pickle 协议版本 0,可以在 pickle 文件中追加项目,但它很混乱,并且手动修改 pickle 文件的内容是 不 好策略。
但是,将新的数据结构附加到现有的 pickle 文件非常容易,您只需要在取消 pickle 文件时适当地处理数据即可。
下面的代码从 pickle 文件中读取一系列字典,将它们全部合并成一个字典。然后它创建一个新的字典并将其附加到现有的 pickle 文件中。
#!/usr/bin/env python
''' Appending data to a pickle file
See
Written by PM 2Ring 2015.07.12
'''
import cPickle as pickle
from random import choice, randint
from string import ascii_lowercase
#Create a random lowercase string
def rand_str(strlen=5):
return ''.join([choice(ascii_lowercase) for _ in xrange(strlen)])
#Name of pickle file
fname = 'pickletest.pkl'
#Attempt to read the dicts from the pickle file
all_data = {}
count = 0
try:
with open(fname, 'rb') as fh:
while True:
d = pickle.load(fh)
count += 1
print 'Record %2d: %s' % (count, d)
all_data.update(d)
except EOFError:
pass
except IOError as e:
print '%s; the file will be created.' % e
print '\nCurrent data\n%s' % all_data
#Create a new record
d = dict((rand_str(), randint(10, 99)) for _ in xrange(5))
print '\nNew data\n%s' % d
#Append the record to the pickle file, using protocol 2
with open(fname, 'ab') as fh:
pickle.dump(d, fh, 2)
这是程序运行 3 次的一些典型输出。
[Errno 2] No such file or directory: 'pickletest.pkl'; the file will be created.
Current data
{}
New data
{'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
#----------------------------------------------------------------
Record 1: {'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
Current data
{'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
New data
{'dptdp': 31, 'waydc': 81, 'zejbe': 34, 'fimgy': 51, 'sdwnp': 90}
#----------------------------------------------------------------
Record 1: {'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
Record 2: {'dptdp': 31, 'sdwnp': 90, 'zejbe': 34, 'fimgy': 51, 'waydc': 81}
Current data
{'fimgy': 51, 'zejbe': 34, 'ejqnt': 36, 'gmpaq': 54, 'veria': 65, 'glsjp': 69, 'waydc': 81, 'dptdp': 31, 'zvvho': 11, 'sdwnp': 90}
New data
{'cavsw': 84, 'unokw': 14, 'irqfh': 60, 'avddt': 50, 'pszdk': 40}
在你的问题中你提到你有几个需要保存的字典和元组的元组。可以调整我的代码来处理这个问题,但是如果你有很多单独的字典和元组,它可能会变得混乱。
将元组的元组转换为字典可能是值得的,因为搜索 dict
比搜索元组或列表快 多 。还可以考虑组合你的字典。如果将所有内容都放入一个单一的扁平字典中是不合适的,请考虑使用字典列表或字典字典。
如果你想存储一个可以动态更新的字典、列表、字符串和数字的结构,你似乎在描述一个面向文档的数据库,比如mongodb。虽然,如果您可以选择只加载一个普通文件,更改您需要的内容并覆盖它,那么这会简单得多。
就我个人而言,我会选择 json 而不是 pickle,因为您只提到了 json 可序列化的类型。优点包括文件可被人类和其他(非Python)软件读取,以及 Pickle 版本的兼容性没有问题。缺点是你不能存储例如函数或 class.
我有一个脚本,还有另一个 Python 文件 mappings.py
,其中包含一堆 dicts
和 tuples-of-tuples
)。其中每一个都在第 0 天填充了 Name 和 Age 值对映射的基线。这些又被添加为参考电子表格的行。
在任何给定的一天,将从新一天的电子表格中读取数据。如果任何记录已经在映射字典或元组之一中,则数据将写入相应的行。
挑战如下:在任何给定的一天,如果输入电子表格中的一行 在 mappings.py
中还没有条目 ,我想:
- 提示用户为给定的姓名指定年龄值
- 以某种方式将这个 Name:Age 对添加到 mappings.py 中适当的字典或元组中,这样在随后的日子里,如果脚本再次遇到该名称,它已经 "knows" 关于它.
所以问题是:我如何追加到文件中的给定数据结构,而不是在内存中,而是在实际文件本身中?因此,如果有问题的字典称为 mydict
,并且我要添加一个新的 Name:Age 对,我可以在内存中做:
mappings.py.mydict[$newName] = [$newAge]
但是我如何实际更新文件,以便使用这个新数据进行保存?最终用户不想直接打开 mappings.py
,因此我将显示一些弹出窗口以接收用户指定的对。然后我想知道如何最好地保存这对。
如果 mappings.py 不需要用户可读,请使用常规字典并将 -load\save 作为 pickle
(参见相关问题)
使用 pickle(或 Python 2 中的 cPickle,因为它比普通 pickle 快得多)的常用方法是
- 从 pickle 文件中解开你的数据结构
- 更新程序中的数据结构
- pickle 更新后的结构,覆盖原始 pickle 文件,可能会保存该原始文件的备份。
酸洗过程相当快,因此除非您要酸洗数百万对(姓名、年龄),否则该策略应该足够了。
将数据附加到 pickle 文件中的单个项目是不切实际的。如果您使用人类可读的 pickle 协议版本 0,可以在 pickle 文件中追加项目,但它很混乱,并且手动修改 pickle 文件的内容是 不 好策略。
但是,将新的数据结构附加到现有的 pickle 文件非常容易,您只需要在取消 pickle 文件时适当地处理数据即可。
下面的代码从 pickle 文件中读取一系列字典,将它们全部合并成一个字典。然后它创建一个新的字典并将其附加到现有的 pickle 文件中。
#!/usr/bin/env python
''' Appending data to a pickle file
See
Written by PM 2Ring 2015.07.12
'''
import cPickle as pickle
from random import choice, randint
from string import ascii_lowercase
#Create a random lowercase string
def rand_str(strlen=5):
return ''.join([choice(ascii_lowercase) for _ in xrange(strlen)])
#Name of pickle file
fname = 'pickletest.pkl'
#Attempt to read the dicts from the pickle file
all_data = {}
count = 0
try:
with open(fname, 'rb') as fh:
while True:
d = pickle.load(fh)
count += 1
print 'Record %2d: %s' % (count, d)
all_data.update(d)
except EOFError:
pass
except IOError as e:
print '%s; the file will be created.' % e
print '\nCurrent data\n%s' % all_data
#Create a new record
d = dict((rand_str(), randint(10, 99)) for _ in xrange(5))
print '\nNew data\n%s' % d
#Append the record to the pickle file, using protocol 2
with open(fname, 'ab') as fh:
pickle.dump(d, fh, 2)
这是程序运行 3 次的一些典型输出。
[Errno 2] No such file or directory: 'pickletest.pkl'; the file will be created.
Current data
{}
New data
{'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
#----------------------------------------------------------------
Record 1: {'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
Current data
{'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
New data
{'dptdp': 31, 'waydc': 81, 'zejbe': 34, 'fimgy': 51, 'sdwnp': 90}
#----------------------------------------------------------------
Record 1: {'veria': 65, 'glsjp': 69, 'zvvho': 11, 'ejqnt': 36, 'gmpaq': 54}
Record 2: {'dptdp': 31, 'sdwnp': 90, 'zejbe': 34, 'fimgy': 51, 'waydc': 81}
Current data
{'fimgy': 51, 'zejbe': 34, 'ejqnt': 36, 'gmpaq': 54, 'veria': 65, 'glsjp': 69, 'waydc': 81, 'dptdp': 31, 'zvvho': 11, 'sdwnp': 90}
New data
{'cavsw': 84, 'unokw': 14, 'irqfh': 60, 'avddt': 50, 'pszdk': 40}
在你的问题中你提到你有几个需要保存的字典和元组的元组。可以调整我的代码来处理这个问题,但是如果你有很多单独的字典和元组,它可能会变得混乱。
将元组的元组转换为字典可能是值得的,因为搜索 dict
比搜索元组或列表快 多 。还可以考虑组合你的字典。如果将所有内容都放入一个单一的扁平字典中是不合适的,请考虑使用字典列表或字典字典。
如果你想存储一个可以动态更新的字典、列表、字符串和数字的结构,你似乎在描述一个面向文档的数据库,比如mongodb。虽然,如果您可以选择只加载一个普通文件,更改您需要的内容并覆盖它,那么这会简单得多。
就我个人而言,我会选择 json 而不是 pickle,因为您只提到了 json 可序列化的类型。优点包括文件可被人类和其他(非Python)软件读取,以及 Pickle 版本的兼容性没有问题。缺点是你不能存储例如函数或 class.