我有泡菜的问题

I'm having problems with pickle

所以,虽然我只是涉足编码,只是在试验,但我想创建一个数据库,以便与我的 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)

我不确定的是为什么我输入的数据在代码运行之间不是 "saved"。 请帮忙

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

您手动输入数据并将其填充到二维数据结构中。
如果您需要在别处使用数据,请将电子表格另存为 .csv 文件并导入。

你的问题是你对变量和赋值如何工作的理解。在下面的代码中,您制作了很多列表。然后你创建一个名为 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 class,然后通过 NPC_ID 将每个 NPC 存储在一个字典中:NPC_CLASS_INSTANCE

更新

下面只是一个简单的示例,我使用 class 表示 npc 并使用字典按 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)