gpt4 book ai didi

python - 不返回 YAML 文件的更新并在字符串更新时返回 TypeError

转载 作者:行者123 更新时间:2023-12-01 09:17:01 30 4
gpt4 key购买 nike

我有代码应该抓取 YAML 文件并将其读入(成功),但也应该能够更新 YAML 返回三个选项之一:

  • 成功更新消息,其中包含对文件的所有更改。
  • 更新失败消息,其中可能包含文件未正确更新的位置。
  • 让用户知道他/她没有传递对文件进行的任何更改(YAML 文件中的冗余条目)。

第二个和第三个选项效果很好,但每当我更新时,第一个选项都会返回 TypeError:字符串索引必须是整数TypeError:'int' object is not iterable我的字典 d 中嵌套字典之外的任何值。

这是我想出的代码:

class YAML_Config:
'''
Class used to interact with .YAML filetypes. Allows the creation of objects \
that can be manipulated and save certain YAML files and configuration settings.
'''

def __init__(self, filename):
'''
Initial defintion. Defines the location for saving a new .YAML file or for loading \
a previous one. The dictionary corresponding to the .YAML file is saved to self.dict. \
If this is a new .YAML file, an empty dictionary is created.

Input Arguments:
-filename: (string) The name of the file where the current .YAML file is \
located or the new .YAML will be saved.
'''
#Get the filename and save it to the class as a property.
self.file = filename

#Check if the file exists...
if os.path.isfile(self.file):

#Prepare to open the file with reading capabilities
with open(self.file,'r') as infile:

#Get a dictionary with all of the YAML informatin.
yaml_dict = yaml.load(infile)

#If the file does not exist...
else:

#Create an empty dictionary to save all YAML data.
yaml_dict = {}

#Create an empty .yaml file with the dictionary.
with open(self.file, 'w') as infile:

#Save updated dictionary to YAML file.
yaml.dump(yaml_dict, infile, default_flow_style=False)

print('YAML configuration file not found. New, empty dictionary, and .yaml file created.')

self.dict=yaml_dict




def update_value(self, kwargs):
'''
Used to update YAML files, and checks that the files were updated properly.
'''
#If these are not keyword arguments, then throw an error.
assert kwargs, 'Input Error'

#Get the YAML dictionary before it is updated.
yaml_dict = self.dict


#Make a copy of the dictionary to compare against later.
yaml_dict_original = copy.deepcopy(self.dict)

#Check if the dictionary is nonetype. This happens if the file is new as the file is empty.
if yaml_dict_original is None:

#Redefine orginal dictionary as an empty dictionary.
yaml_dict_original={}

#The new dictionary will simply be what is passed to the function.
yaml_dict=kwargs

else:

#Update the original dictionary and update it with the arguments passed.
#This also updates self.dict as yaml_dict is simply a reference to
#that dictionary, not a copy of it.
yaml_dict.update(kwargs)


#Check if changes were made
if (yaml_dict==yaml_dict_original) is False:

#Open the YAML file to write to it.
with open(self.file, 'w') as outfile:

#Save updated dictionary to YAML file.
yaml.dump(self.dict, outfile, default_flow_style=False)


#Check that the file actually updated properly:

#Double-check the file that it actually updated.
with open(self.file, 'r') as infile:

lastupdate = yaml.load(infile)

#Get any nonmatching values between what should be in the YAML file and what actually is.
errors = { k : yaml_dict[k] for k in set(yaml_dict) - set(lastupdate) }

#Find out what changed in the YAML file.
edits = { k : yaml_dict_original[k] for k in set(yaml_dict_original) - set(lastupdate) }

#Check if errors is not empty. Evaluating dictionaries as boolean either returns True (not empty)
#or False (empty).
if bool(errors) is True:

#First line of return print statement.
print('The following entries did not update successfully:')

#Loop through keys in errors
for n in errors:

#Print the current key
print (n)

#Loop through entries of current key
for m in errors[n]:

#Print current entry of current key
print (m,':',errors[n][m])

#Saved properly, check for edits and display to user.
else:

#Find where any edits were made.
edits = {k: yaml_dict_original[k] for k in yaml_dict_original if k in lastupdate and yaml_dict_original[k] != lastupdate[k]}

#Show user what edits were successfuly made.
print('%s was successfully updated with the following changes:' % os.path.basename(self.file))

#Loop through keys in edits
for n in edits:

#Print the current key
print (n)

#Loop through entries of current key
for m in edits[n]:

#Print current entry of current key
print (m,':',edits[n][m])

#If no changes were made...
else:

#Show user what edits were successfuly made.
print('No changes to %s were passed. File not updated.' %

os.path.basename(self.file))



test=YAML_Config(r'...Path\Python Work\yaml_test.yaml')

d = {'A': 7, 'B':{'C':'D', 'D':False, 'E':'Julio'},\
'The Real C': {'J?':'Yes, this is J.', 'K' : 241},'Q' : 'PQ'}

test.update_value(d)

第一个错误部分:

b = {'A': '', 'B':{'C':'D', 'D':False, 'E':'Julio'},\
'The Real C': {'J?':'Yes, this is J.', 'K' : 241},'Q' : 'PQ'}

#TypeError: string indices must be integers.
test.update_value(b)

第二个错误部分:

f = {'A': 7, 'B':{'C':'D', 'D':False, 'E':'Julio'},\
'The Real C': {'J?':'Yes, this is J.', 'K' : 241},'Q' : 2}

#TypeError: 'int' object is not iterable.
test.update_value(f)

每次运行此代码时,YAML 文件都会更新。所以实际的更新正在工作,但我不太确定为什么我找不到字典更新的索引。我对 Python 有点生疏,而且对 YAML 还很陌生,所以我可能会在这里遗漏一些明显的东西。

我使用的是 Python 3.6.5。

最佳答案

您的代码在这一行出错:

                    # Loop through entries of current key
for m in edits[n]:

此时 edits 是一个字典:{A: 7}(因为 A 是具有更改值的键)。您的代码似乎只预测复杂值的变化(例如 B 的变化),因为如果您这样做:

b = {'A': 7, 'B':{'C':'D', 'D':True, 'E':'Julio'},\
'The Real C': {'J?':'Yes, this is J.', 'K' : 241},'Q' : 'PQ'}

你得到:

test.yaml was successfully updated with the following changes:
B
C : D
D : False
E : Julio

因此,您应该重新考虑您的“报告”并将其更新为不仅可以处理 dict 值,还可以处理 list 和基元(YAML 标量)的值:字符串、整数、 bool 值等):

            # Show user what edits were successfuly made.
print('{} was successfully updated with the following changes:'.format(os.path.basename(self.file)))
# Loop through keys in edits
for n in edits:
# Loop through entries of current key
if isinstance(edits[n], dict):
# Print the current key
print(n)
for m in edits[n]:
# Print current entry of current key
print(m, ':', edits[n][m])
elif isinstance(edits[n], list):
# Print the current key followed by the elements
print(n)
for m in edits[n]:
# Print current entry of current key
print('- ', [m])
else: # scalar
print('{}: {}'.format(n, edits[n]))

然后你的输出将是:

test.yaml was successfully updated with the following changes:
A: 7
test.yaml was successfully updated with the following changes:
A:
Q: PQ

(假设您相继运行两个额外更新)。

关于python - 不返回 YAML 文件的更新并在字符串更新时返回 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51153553/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com