简体   繁体   English

用pickle加载类的实例?

[英]Loading an instance of a class with pickle?

I am trying to use pickle to load an instance, which I have previously saved.我正在尝试使用 pickle 加载一个我之前保存的实例。

My code currently goes like so:我的代码目前是这样的:

with open ("Character.pkl", "rb") as f:
      self = pickle.load(f)

While I am still inside the class, I can then access different attributes of my character.当我还在课堂上时,我可以访问角色的不同属性。

# Code
with open ("Character.pkl", "rb") as f:
      self = pickle.load(f)
print(self.damage)

# Output
--> 10

However, outside of the class, when I try to access this, it throws an Attribute Error.但是,在课程之外,当我尝试访问它时,它会引发属性错误。

For reference, here is all the code:作为参考,这里是所有的代码:

# Modules

# For managing the saved and loaded dictionaries
import json

# To obtain the ability to randomly choose between items of a list
import random

# To manage folders and files
import os

# To clear the terminal
import click

# To save and load instances
import _pickle as pickle
class character:



  # When this class is initiated...
  def create(self, first, last, gender, race, class_, background, morales, attitude, accountName, gameName):

    # Explain character creation instructions
    print("Welcome to the character creator!\n\nHere, you will create your character for the upcoming adventures.\n\nOn any question, type '0' for a random option.")
    input("\nPress enter to continue...\t")

    # Genders to be randomly selected from if that option is chosen
    genders = ["male", "female"]

    # A list of the inputted character features
    features = [first, last, gender, race, class_, background, morales, attitude]

    # If the gender is to be randomly selected
    if gender == str(0):

      # Update the gender section of features to the randomly selected gender
      features[2] = random.choice(genders)

    # List of feature types for refering to files
    features_str = [str(features[2])+"first", "last", "gender", "race", "class", "background", "morales", "attitude"]

    # Get to the right directory to get random information
    os.chdir("../../../Code Sections/Info/")

    # Check through each inputted feature
    for i in range (len(features_str)):

      # If random
      if features[i] == str(0):

        # Open the file refering to the feature
        with open ("randoms" + ".json", "r") as f:

          # Load the dictionary
          loaded_dict = json.load(f)

        # Choose a random feature from the dictionary
        features[i] = random.choice(loaded_dict.get(features_str[i]))

    # Capitalize the first letter of the gender after using it for file opening (so it can be displayed)
    features[2] = features[2].capitalize()

    # Get to the account info directory
    os.chdir("../../Accounts/Account - {}/Game Saves/{}".format(accountName, gameName))

    # Give the character its desired attributes
    self.first, self.last, self.gender, self.race, self.class_, self.background, self.morales, self.attitude = features
    self.fullname = "{} {}".format(self.first, self.last)
    self.alignment = "{} {}".format(self.attitude, self.morales)
    self.damage = "10"
    self.defence = "15"

    # A dictionary of all features
    self.features = {"First Name":self.first, "Surname":self.last, "Full Name":self.fullname, "Gender":self.gender, "Race":self.race, "Class":self.class_, "Background":self.background, "Attitude":self.attitude, "Morales":self.morales, "Alignment":self.alignment, "Damage":self.damage, "Defence":self.defence}

    # Create a formatted version of the character data to be stored
    with open ("Character Sheet.txt", "w+") as f:
      for i in range (len(self.features)):
        f.write("\n" + list((self.features).keys())[i] + ": " + list((self.features).values())[i])

    # Store the formatted file's contents as the character's info sheet
    with open ("Character Sheet.txt", "r") as f:
      self.character_sheet = "Your Character:\n" + f.read()

    # Remove the text file
    os.remove("Character Sheet.txt")

    # Save this instance
    with open ("Character.pkl", "wb") as f:
      pickle.dump(self, f, -1)



  def load(self, accountName, gameName):

    # Get to the account info directory
    os.chdir(gameName)

    with open ("Character.pkl", "rb") as f:
      self = pickle.load(f)

    print(self.features) # <-- This prints the attributes fine, without any error



  def __init__(self, packaged_info):

    called_for, account_info, game_info = packaged_info

    if called_for == "create":
      self.create(input("\nWhat is your character's first name?\n\nInput:\t"), input("\nWhat is your character's last name?\n\nInput:\t"), input("\nWhat is your character's gender?\n\nInput:\t").lower(), input("\nWhat is your character's race?\n\nInput:\t"), input("\nWhat is your character's class?\n\nInput:\t"), input("\nWhat is your character's background?\n\nInput:\t"), input("\nWhat are your character's morales? (Eg. Neutral)\n\nInput:\t"), input("\nWhat is your character's attitude towards society? (Eg. Lawful)\n\nInput:\t"), account_info.get("Account Name"), game_info.get("Game Name"))
    elif called_for == "load":
      self.load(account_info.get("Account Name"), game_info.get("Game Name"))




 # The order in which this file is run
def run(packaged_info):

  # Unpackage info
  account_info, game_info, called_from = packaged_info

  # Clear the terminal
  click.clear()

  # Make character with desired attributes
  user_character = Character([called_from, account_info, game_info])
  print(user_character.features) # <-- This throws the attribute error
  return [account_info, game_info, user_character]

Apologies in advance;提前道歉; I am very new to OOP (and python as a whole) so my code is likely not the best, nor my terminology.我对 OOP(以及整个 Python)非常陌生,所以我的代码可能不是最好的,也不是我的术语。 I also did some research before posting this, but couldn't find an answer (that I could understand), so apologies if this is a duplicate post.我在发布之前也做了一些研究,但找不到答案(我能理解),如果这是一个重复的帖子,我深表歉意。

If anyone could help me with this, it would be much appreciated.如果有人能帮助我解决这个问题,我将不胜感激。

I managed to fix my issue by returning pickle.load(f) and calling the load() method directly instead of through the init () method.我设法通过返回 pickle.load(f) 并直接调用 load() 方法而不是通过init () 方法来解决我的问题。

The updated code is below:更新后的代码如下:

# Modules

# For managing the saved and loaded dictionaries
import json

# To obtain the ability to randomly choose between items of a list
import random

# To manage folders and files
import os

# To clear the terminal
import click

# To save and load instances
import _pickle as pickle

# For each character in-game
class Character:

  # When this class is initiated...
  def create(self, first, last, gender, race, class_, background, morales, attitude, accountName, gameName):

    # Explain character creation instructions
    print("Welcome to the character creator!\n\nHere, you will create your character for the upcoming adventures.\n\nOn any question, type '0' for a random option.")
    input("\nPress enter to continue...\t")

    # Genders to be randomly selected from if that option is chosen
    genders = ["male", "female"]

    # A list of the inputted character features
    features = [first, last, gender, race, class_, background, morales, attitude]

    # If the gender is to be randomly selected
    if gender == str(0):

      # Update the gender section of features to the randomly selected gender
      features[2] = random.choice(genders)

    # List of feature types for refering to files
    features_str = [str(features[2])+"first", "last", "gender", "race", "class", "background", "morales", "attitude"]

    # Get to the right directory to get random information
    os.chdir("../../../Code Sections/Info/")

    # Check through each inputted feature
    for i in range (len(features_str)):

      # If random
      if features[i] == str(0):

        # Open the file refering to the feature
        with open ("randoms" + ".json", "r") as f:

          # Load the dictionary
          loaded_dict = json.load(f)

        # Choose a random feature from the dictionary
        features[i] = random.choice(loaded_dict.get(features_str[i]))

    # Capitalize the first letter of the gender after using it for file opening (so it can be displayed)
    features[2] = features[2].capitalize()

    # Get to the account info directory
    os.chdir("../../Accounts/Account - {}/Game Saves/{}".format(accountName, gameName))

    # Give the character its desired attributes
    self.first, self.last, self.gender, self.race, self.class_, self.background, self.morales, self.attitude = features
    self.fullname = "{} {}".format(self.first, self.last)
    self.alignment = "{} {}".format(self.attitude, self.morales)
    self.damage = "10"
    self.defence = "15"

    # A dictionary of all features
    self.features = {"First Name":self.first, "Surname":self.last, "Full Name":self.fullname, "Gender":self.gender, "Race":self.race, "Class":self.class_, "Background":self.background, "Attitude":self.attitude, "Morales":self.morales, "Alignment":self.alignment, "Damage":self.damage, "Defence":self.defence}

    # Create a formatted version of the character data to be stored
    with open ("Character Sheet.txt", "w+") as f:
      for i in range (len(self.features)):
        f.write("\n" + list((self.features).keys())[i] + ": " + list((self.features).values())[i])

    # Store the formatted file's contents as the character's info sheet
    with open ("Character Sheet.txt", "r") as f:
      self.character_sheet = "Your Character:\n" + f.read()

    # Remove the text file
    os.remove("Character Sheet.txt")

    # Save this instance
    with open ("Character.pkl", "wb") as f:
      pickle.dump(self, f, -1)

  def load(self, accountName, gameName):

    # Get to the account info directory
    os.chdir(gameName)

    with open ("Character.pkl", "rb") as f:
      return pickle.load(f)

  def __init__(self, packaged_info):

    called_for, account_info, game_info = packaged_info

    if called_for == "create":
      self.create(input("\nWhat is your character's first name?\n\nInput:\t"), input("\nWhat is your character's last name?\n\nInput:\t"), input("\nWhat is your character's gender?\n\nInput:\t").lower(), input("\nWhat is your character's race?\n\nInput:\t"), input("\nWhat is your character's class?\n\nInput:\t"), input("\nWhat is your character's background?\n\nInput:\t"), input("\nWhat are your character's morales? (Eg. Neutral)\n\nInput:\t"), input("\nWhat is your character's attitude towards society? (Eg. Lawful)\n\nInput:\t"), account_info.get("Account Name"), game_info.get("Game Name"))

 # The order in which this file is run
def run(packaged_info):

  # Unpackage info
  account_info, game_info, called_from = packaged_info

  # Clear the terminal
  click.clear()

  # Make character with desired attributes
  if called_from == "create":
    user_character = Character([called_from, account_info, game_info])
  elif called_from == "load":
    user_character = Character([called_from, account_info, game_info]).load(account_info.get("Account Name"), game_info.get("Game Name"))
  return [account_info, game_info, user_character]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM