Python 带Pickle的预设变量
好的,基本上我想实现的是,在第一次运行程序时,将MaTC、AnTC、AuTC、AlTC和JaTC变量预设为1、2、3、3和3。但是当我想加2表示MaTC使之为3时,当我再次启动程序时,我希望它在启动时等于3。我几天前刚开始使用python,我很想收到反馈 使用异常处理文件不存在的情况(即程序的第一次运行) 我也倾向于使用dict将所有变量存储在单个文件中:Python 带Pickle的预设变量,python,pickle,Python,Pickle,好的,基本上我想实现的是,在第一次运行程序时,将MaTC、AnTC、AuTC、AlTC和JaTC变量预设为1、2、3、3和3。但是当我想加2表示MaTC使之为3时,当我再次启动程序时,我希望它在启动时等于3。我几天前刚开始使用python,我很想收到反馈 使用异常处理文件不存在的情况(即程序的第一次运行) 我也倾向于使用dict将所有变量存储在单个文件中: try: f = open("MaTCFile.dat", "rb") # Pickle is not a .txt format
try:
f = open("MaTCFile.dat", "rb") # Pickle is not a .txt format
MaTC = pickle.load(f)
except IOError:
# Initialise default value
MaTC = 1
这将使程序更易于管理。这是您的程序的重构版本。它使用了
pickle
模块,并演示了pickletools
、zlib
和其他一些模块的用法。希望这些代码能帮助您进一步编写程序。您可能希望在将来研究的一个主题是数据库
default_data = {
"MaTC": 1, "AnTC": 2, # ... etc.
导入操作系统
进口泡菜
导入pickle工具
导入系统
进口zlib
设置\u文件='SETTINGS.sav'
def main():
“”“为用户提供清洗应用程序。”“”
设置=加载设置(设置文件)
打印(“你好,雅各布!”)
尽管如此:
如果显示菜单(设置,
选择清洁剂,
编辑清洁信息,
含蓄的,
关闭程序):
打破
保存(设置文件)
def加载_设置(路径):
“”“可以创建设置架构并从文件加载它们。”“”
设置=名称空间(mares=参数(1,为正整数),
andres=参数(2,为正整数),
austin=参数(3,为正整数),
al=参数(3,为正整数),
jacob=参数(3,为正整数))
如果os.path.isfile(路径):
设置。加载(路径)
返回设置
def为正整数(值):
“”“请确保该值对设置有效。”“”
返回isinstance(值,int)和值>=0
def显示菜单(上下文,*参数):
“”“帮助向用户显示菜单。”“”
对于选项,枚举中的函数(args,1):
打印(选项“-”,函数._u文件_;)
尽管如此:
number=get_int('请输入一个选项:')-1
如果0,非常感谢!这帮了大忙!!
default_data = {
"MaTC": 1, "AnTC": 2, # ... etc.
import os
import pickle
import pickletools
import sys
import zlib
SETTINGS_FILE = 'settings.sav'
def main():
"""Present the user with a cleaning application."""
settings = load_settings(SETTINGS_FILE)
print('Hello, Jacob!')
while True:
if show_menu(settings,
select_cleaners,
edit_cleaning_information,
reserved,
close_program):
break
settings.save(SETTINGS_FILE)
def load_settings(path):
"""Create the settings schema and load them from file is possible."""
settings = Namespace(mares=Parameter(1, is_positive_int),
andres=Parameter(2, is_positive_int),
austin=Parameter(3, is_positive_int),
al=Parameter(3, is_positive_int),
jacob=Parameter(3, is_positive_int))
if os.path.isfile(path):
settings.load(path)
return settings
def is_positive_int(value):
"""Ensure that the value is valid for the settings."""
return isinstance(value, int) and value >= 0
def show_menu(context, *args):
"""Help display a menu to the user."""
for option, function in enumerate(args, 1):
print(option, '-', function.__doc__)
while True:
number = get_int('Please enter an option: ') - 1
if 0 <= number < len(args):
return args[number](context)
else:
print('Your number was out of range.')
def get_int(prompt):
"""Get a valid number from the user."""
while True:
try:
text = input(prompt)
except EOFError:
sys.exit()
else:
try:
return int(text)
except ValueError:
print('You did not enter an integer.')
def select_cleaners(context):
"""Choose this to select your cleaner."""
print('Selecting Cleaning Function')
def edit_cleaning_information(context):
"""You can edit the cleaning information."""
show_menu(context, check_cleaning_info, enter_new_cleaning_info)
def reserved(context):
"""This is reserved for future use."""
print('NOT AVAILABLE')
def close_program(context):
"""Close the program."""
return True
def check_cleaning_info(context):
"""Show all cleaning info."""
print('Mares:', context.mares)
print('Andres:', context.andres)
print('Austin:', context.austin)
print('Al:', context.al)
print('Jacob:', context.jacob)
def enter_new_cleaning_info(context):
"""Enter in additional cleaning information."""
while True:
name = input('Who needs cleaning info adjusted? ').capitalize()
if name == 'Mares':
context.mares += get_int('Add to Mares: ')
elif name == 'Andres':
context.andres += get_int('Add to Andres: ')
elif name == 'Austin':
context.austin += get_int('Add to Austin: ')
elif name == 'Al':
context.al += get_int('Add to Al: ')
elif name == 'Jacob':
context.jacob += get_int('Add to Jacob: ')
else:
continue
break
###############################################################################
class _Settings:
"""_Settings(*args, **kwargs) -> _Settings instance"""
@staticmethod
def _save(path, obj):
"""Save an object to the specified path."""
data = zlib.compress(pickletools.optimize(pickle.dumps(obj)), 9)
with open(path, 'wb') as file:
file.write(data)
@staticmethod
def _load(path):
"""Load an object from the specified path."""
with open(path, 'rb') as file:
data = file.read()
return pickle.loads(zlib.decompress(data))
class Namespace(_Settings):
"""Namespace(**schema) -> Namespace instance"""
def __init__(self, **schema):
"""Initialize the Namespace instance with a schema definition."""
self.__original, self.__dynamic, self.__static, self.__owner = \
{}, {}, {}, None
for name, value in schema.items():
if isinstance(value, _Settings):
if isinstance(value, Namespace):
if value.__owner is not None:
raise ValueError(repr(name) + 'has an owner!')
value.__owner = self
self.__original[name] = value
else:
raise TypeError(repr(name) + ' has bad type!')
def __setattr__(self, name, value):
"""Set a named Parameter with a given value to be validated."""
if name in {'_Namespace__original',
'_Namespace__dynamic',
'_Namespace__static',
'_Namespace__owner',
'state'}:
super().__setattr__(name, value)
elif '.' in name:
head, tail = name.split('.', 1)
self[head][tail] = value
else:
attr = self.__original.get(name)
if not isinstance(attr, Parameter):
raise AttributeError(name)
attr.validate(value)
if value == attr.value:
self.__dynamic.pop(name, None)
else:
self.__dynamic[name] = value
def __getattr__(self, name):
"""Get a Namespace or Parameter value by its original name."""
if '.' in name:
head, tail = name.split('.', 1)
return self[head][tail]
if name in self.__dynamic:
return self.__dynamic[name]
attr = self.__original.get(name)
if isinstance(attr, Namespace):
return attr
if isinstance(attr, Parameter):
return attr.value
raise AttributeError(name)
__setitem__ = __setattr__
__getitem__ = __getattr__
def save(self, path):
"""Save the state of the entire Namespace tree structure."""
if isinstance(self.__owner, Namespace):
self.__owner.save(path)
else:
self._save(path, {Namespace: self.state})
def load(self, path):
"""Load the state of the entire Namespace tree structure."""
if isinstance(self.__owner, Namespace):
self.__owner.load(path)
else:
self.state = self._load(path)[Namespace]
def __get_state(self):
"""Get the state of this Namespace and any child Namespaces."""
state = {}
for name, types in self.__static.items():
box = state.setdefault(name, {})
for type_, value in types.items():
box[type_] = value.state if type_ is Namespace else value
for name, value in self.__original.items():
box = state.setdefault(name, {})
if name in self.__dynamic:
value = self.__dynamic[name]
elif isinstance(value, Parameter):
value = value.value
else:
box[Namespace] = value.state
continue
box.setdefault(Parameter, {})[type(value)] = value
return state
def __set_state(self, state):
"""Set the state of this Namespace and any child Namespaces."""
dispatch = {Namespace: self.__set_namespace,
Parameter: self.__set_parameter}
for name, box in state.items():
for type_, value in box.items():
dispatch[type_](name, value)
def __set_namespace(self, name, state):
"""Set the state of a child Namespace."""
attr = self.__original.get(name)
if not isinstance(attr, Namespace):
attr = self.__static.setdefault(name, {})[Namespace] = Namespace()
attr.state = state
def __set_parameter(self, name, state):
"""Set the state of a child Parameter."""
attr = self.__original.get(name)
for type_, value in state.items():
if isinstance(attr, Parameter):
try:
attr.validate(value)
except TypeError:
pass
else:
if value == attr.value:
self.__dynamic.pop(name, None)
else:
self.__dynamic[name] = value
continue
if not isinstance(value, type_):
raise TypeError(repr(name) + ' has bad type!')
self.__static.setdefault(name, {}).setdefault(
Parameter, {})[type_] = value
state = property(__get_state, __set_state, doc='Namespace state property.')
class Parameter(_Settings):
"""Parameter(value, validator=lambda value: True) -> Parameter instance"""
def __init__(self, value, validator=lambda value: True):
"""Initialize the Parameter instance with a value to validate."""
self.__value, self.__validator = value, validator
self.validate(value)
def validate(self, value):
"""Check that value has same type and passes validator."""
if not isinstance(value, type(self.value)):
raise TypeError('Value has a different type!')
if not self.__validator(value):
raise ValueError('Validator failed the value!')
@property
def value(self):
"""Parameter value property."""
return self.__value
###############################################################################
if __name__ == '__main__':
main()