python - 用pickle加载一个类的实例?
问题描述
我正在尝试使用 pickle 加载我之前保存的实例。
我的代码目前是这样的:
with open ("Character.pkl", "rb") as f:
self = pickle.load(f)
当我还在课堂上时,我可以访问我角色的不同属性。
# Code
with open ("Character.pkl", "rb") as f:
self = pickle.load(f)
print(self.damage)
# Output
--> 10
但是,在课堂之外,当我尝试访问它时,它会引发属性错误。
作为参考,这里是所有代码:
# 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]
提前道歉;我对 OOP(以及整个 python)非常陌生,所以我的代码可能不是最好的,也不是我的术语。在发布之前我也做了一些研究,但找不到答案(我能理解),所以如果这是重复的帖子,我深表歉意。
如果有人可以帮助我,将不胜感激。
解决方案
我设法通过返回 pickle.load(f) 并直接调用 load() 方法而不是通过init () 方法来解决我的问题。
更新后的代码如下:
# 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]
推荐阅读
- android - 保持 Intent 服务运行?
- sql-server - TSQL 强制转换视图定义中的所有列
- vue.js - ASP.NET Core SPA Vue 模板与 Vue CLI
- c++ - 具有 unique_ptr 的 CRTP 导致段错误
- python - Python-Sphinx:文档字符串代码测试以及通过 IPython 指令运行代码?
- opencv - Tensorflow如何从OpenCV图像帧中读取张量
- java - Android Studios:点击按钮解锁屏幕方向
- visual-studio - 如何在 Visual Studio 中更改程序图标?
- php - 尝试从作曲家安装 laravel 时缺少 PHP 扩展 zip
- python - 无法返回 [0,0] 和的空数组