【问题标题】:I'm having problems with pickle我有泡菜的问题
【发布时间】:2020-04-25 20:04:30
【问题描述】:

所以,虽然我只是涉足编码和试验,但我想为我的 D&D 活动需要的 170 个(目前)NPC 创建一个易于交互的数据库。

事实证明,在不理解代码的情况下将代码块混在一起并不总是有效,令人震惊。

所以,这是我的代码,虽然我确信它会让你流血,但我只需要让它工作:

#import pickle
import pickle

#NPC ID generator 
counter=1
NPCS=[]
while counter<=170 :
    NPCS.append(counter)
    counter+=1


if len(NPCS)==170:
    print ("True")
else :
    print ("False") ; raise SystemExit 

#Attributes
name=[] ; occupation=[];weakness=[];need=[];desire=[];enemy=[];rumor=[];secret=[];passion=[]
redeemdamningquality=[];happy=[];occdesire=[];occcomplication=[];pcopinion=[];accomplish=[]
magical=[];politinfl=[];resource=[];intel=[];research=[]

NPCatt=[name,occupation,weakness,need,desire,enemy,rumor,secret,passion,redeemdamningquality,happy,occdesire,occcomplication,pcopinion, accomplish,magical,politinfl,resource,intel,research]  

#open a pickle file
newfile = 'NPCatt.pk'
#load your data back to memory when you need it
with open(newfile, 'rb') as fi:
  NPCatt = pickle.load(fi)

# Data Input 
print ("Enter the numerical code of the NPC you wish to modify")
raw=int(input())

if raw != ValueError :
    print ("Enter Name of NPC" + str(raw) ) ; a=input()
    if a!="":
        name.insert(raw+1,a);print ("Name Inserted Successfully")
    else:
        print ("Skipped!")

    print ("Enter Occupation of NPC" + str(raw) ) ;a=input()
    if a!="":
        occupation.insert(raw+1,a);print("Occupation Inserted Successfully")
    else:
        print ("Skipped!")
else :
    print ("BAD VALUE")

for x in (NPCatt) :
    if len(x)!=0 :
         print (x)
    elif len(x)>=170:
        print (x) ; print ("Has too many items")
    else :
        print (str(x) + "is empty")




with open(newfile, 'wb') as fi:
  # dump your data into the file
  pickle.dump(NPCatt, fi)

我不确定的是为什么我输入的数据在代码运行之间没有“保存”。 请帮忙

【问题讨论】:

  • 你能否为你的问题做一个最小可重现的例子。目前,如果我尝试加载一个腌制对象,对其进行修改,然后将其再次腌制回文件,这些更改确实会被保存。
  • 老实说克里斯,我不知道该怎么做。我可以告诉你,代码运行没有错误或异常,只是没有保存我想要的数据。
  • 我没有,怎么可能?
  • 不是文件系统问题。这是 OP 如何理解变量工作的问题。
  • @Icarus 我查看了您的代码并发现了问题并发布了一个答案,解释了它发生的原因以及如何更改它以在您当前的代码中工作,但也建议您可能有猜测这段代码不是最好的方法

标签: python pickle


【解决方案1】:

我知道这根本不是您想要的,但是使用电子表格来做这件事不是更容易吗?

无论如何,您都是手动输入数据并将其填充到二维数据结构中。
如果您需要在其他地方使用数据,请将电子表格保存为 .csv 文件并导入。

【讨论】:

  • 绝对会。但这是我在解决 irl 问题的同时涉足编码的一种方式
【解决方案2】:

您的问题是您对变量和赋值如何工作的理解。在下面的代码中,您制作了很多列表。然后,您创建一个名为 NPCatt 的变量,其中引用了您创建的所有这些列表。

#Attributes
name=[] ; occupation=[];weakness=[];need=[];desire=[];enemy=[];rumor=[];secret=[];passion=[]
redeemdamningquality=[];happy=[];occdesire=[];occcomplication=[];pcopinion=[];accomplish=[]
magical=[];politinfl=[];resource=[];intel=[];research=[]

NPCatt=[name,occupation,weakness,need,desire,enemy,rumor,secret,passion,redeemdamningquality,happy,occdesire,occcomplication,pcopinion, accomplish,magical,politinfl,resource,intel,research]

因此,如果我要查看 NPCatt[0],它将是所有 npc 名称的列表。这很好。但是你然后继续做

with open(newfile, 'rb') as fi:
  NPCatt = pickle.load(fi)

现在变量 NPCatt 并不指向您的所有列表。它现在指向未腌制的对象。因此,当您稍后执行 names.append 时,它将更新名称列表,但 NPCatt 不再指向此列表。因此,当您腌制 NPCatt 时,您只会腌制您从文件中加载的内容。

这是您错误的症结所在。如果您想在解封后修改 NPCatt 保存的数据,那么您应该像

一样访问它
   if a!="":
        NPCatt[0].insert(raw+1,a);print ("Name Inserted Successfully")
    else:
        print ("Skipped!")

    print ("Enter Occupation of NPC" + str(raw) ) ;a=input()
    if a!="":
        NPCatt[1].insert(raw+1,a);print("Occupation Inserted Successfully")
    else:
        print ("Skipped!")

但是这变得非常混乱,并且不清楚哪个列表正在更新,因为您必须通过索引位置来引用它。你最好在这里查看python字典,因为你可以通过名称而不是索引位置来引用事物。或者,如果你愿意考虑创建一个 NPC 类,然后将每个 NPC 存储在 NPC_ID 的字典中,那就更好了:NPC_CLASS_INSTANCE

更新

下面只是一个简单的例子,我使用一个用于 npc 的类和一个 dict 来按 id 存储 npc。这只是放在一起,没有任何真正的设计或专业和缺点,只是为了向您展示示例。

# import pickle
import pickle
npcs_pickle_file = 'NPCatt.pk'
npc_count = 170

class NPC:
    def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
                 rumor="", secret="", passion="", redeem_damning_quality="", happy="",
                 occ_desire="", occ_complication="", pc_opinion="", accomplish="", magical="",
                 politinfl="", resource="", intel="", research=""):

        # Attributes
        self.name = name
        self.occupation = occupation
        self.weakness = weakness
        self.need = need
        self.desire = desire
        self.enemy = enemy
        self.rumor = rumor
        self.secret = secret
        self.passion = passion
        self.redeem_damning_quality = redeem_damning_quality
        self.happy = happy
        self.occ_desire = occ_desire
        self.occ_complication = occ_complication
        self.pc_opinion = pc_opinion
        self.accomplish = accomplish
        self.magical = magical
        self.politinfl = politinfl
        self.resource = resource
        self.intel = intel
        self.research = research

    def __str__(self):
        npc_output = "####NPC SUMMARY####\n"
        for att, val in self.__dict__.items():
            if val:
                npc_output += (f"{att} = {val}\n")
        return npc_output

# open a pickle file
# load your data back to memory when you need it
try:
    with open(npcs_pickle_file, 'rb') as fi:
        npcs = pickle.load(fi)
except FileNotFoundError as fne:
    #file doesnt exist prob first time running so create a dict with the 170 npc id's
    npcs = {id: None for id in range(npc_count)}


#select an NPC to modify / create
npc_id = None
while not npc_id:
    try:
        npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
    except ValueError as ve:
        print("You must provide a numerical id")

    if npc_id < 0 or npc_id >= npc_count:
        npc_id = None
        print(f"you must provide a value between 0 and {npc_count}")

name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")

if npcs[npc_id]:
    npc = npcs[npc_id]
    print(npc)
    modify = input("This NPC already exists do you want to continue and change them? (y/n): ")
    if modify.lower() == "y":
        npc.name = name
        npc.occupation = occupation
else:
    npcs[npc_id] = NPC(name=name, occupation=occupation)

print(npcs[npc_id])
with open(npcs_pickle_file, 'wb') as fi:
    # dump your data into the file
    pickle.dump(npcs, fi)

【讨论】:

  • 好的,那我去看看类和字典,谢谢你把问题简单化了,让我明白了^.^
  • @Icarus 我已经用一个示例更新了我的答案,说明如何使用类/字典来存储 npcs
  • 天哪!太感谢了!我会弄乱你的例子来了解它是如何工作的,这对我来说是一个金矿:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
相关资源
最近更新 更多