#python #module #return-value
#python #модуль #возвращаемое значение
Вопрос:
Я тот, кого большинство людей, вероятно, считают начинающим программистом. Я довольно успешно продвигаюсь в попытке создать свою собственную текстовую «игру», и она уже состоит из четырех отдельных модулей. Все работает великолепно в том смысле, что начинается с «меню» для игры, в котором используется библиотека cmd для перемещения вас куда угодно. Я могу создать символ и сохранить его в файл json просто отлично, но на этом все заканчивается, так как данные сохраняются просто отлично, но я не могу найти способ взять эти данные и переместить их в другие модули, в которых они необходимы, без загрузки jsonфайл каждый раз, в каждом модуле.
Краткое наложение кода выглядит примерно так:
diceGame.py
import cmd
import charCreation
import charInfo
import charFeats
import charWrite
class Hub(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "Hub > "
print("Welcome to the Hub. From here, you can create your first character and view the character sheet with the"
" 'char' command, or review and select feats with the 'feats' command. For more information on both,"
" please type help <command>.")
def do_char(self, args):
"""this command will give you access to the 'create' command, to create your character for this account. It
will also give you access to the 'viewchar' command, which will provide you with a basic character sheet
containing all needed information"""
character = Character()
character.cmdloop()
def do_feats(self, args):
"""this command will give you access to the commands to look at all feats in the game and their descriptions
and any required qualifications that are needed before taking the feat. Feats are divided into three catagories:
Strength, Dexterity, and Constition.
"""
feats = Feats()
feats.cmdloop()
def do_quit(self, args):
"""Exits the bot"""
print("Closing closing the bot.")
return True
class Character(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "Character > "
print("Welcome to Character Creation. To begin, type 'create'. To exit, type 'quit'. For a list of commands and"
" their descriptions, type 'help'")
def do_create(self, args):
"""Use this command to create a new character. Note you can only have one character per account. Feats are
selected using the 'feats' option"""
basics = charCreation.Character.basics()
abilities = charCreation.Character.abilities(basics)
charWrite.SaveModule.save(self, basics, abilities)
def do_viewchar(self, args):
"""Use this command to get a list of your character statics"""
charInfo.charSheet()
def do_quit(self, args):
"""Leaves character Creation"""
print("Closing Character Creation.")
return True
class Feats(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "Feats > "
print("Welcome to Feat Selection. Here you can view the lists of feats for any given category: Strength"
" Dexterity, Constitution, and. Simply type 'getfeat' to start the process.")
def do_getfeat(self,args):
charFeats.feats()
def do_quit(self, args):
"""Leaves Feat Selection"""
print("Closing Feat Selection.")
return True
if __name__ == "__main__":
hub = Hub()
hub.cmdloop()
Вышеуказанное работает просто отлично. Переходим к созданию базового персонажа, затем к способностям (с передачей значений из basics), затем к модулю charWrite (опять же, с успешной передачей basics и abilities). Теперь предполагается, что charWrite — это мой универсальный магазин для открытия, сброса и загрузки json. Идея состоит в том, чтобы выполнить всю работу там и сохранить информацию в переменных для передачи в другие места. Как я уже сказал, я чувствую, что открытие, загрузка, сброс и весь этот джаз в каждом отдельном модуле просто неправильны и плохая практика. Итак, у меня есть следующее, написанное в charWrite.
charCreation.py
'''
key = level
Element = value
0 = hit Points
1 = minimum damage
2 = maximum damage
3 = total ability points
4 = total number of feats
5 = base to hit modifier
6 = base Armor Class
7 = experience Points to next level
Strictly speaking, this script only needs the first key in the levelDict. However, the entire dictionary is placed here
if needed later.
'''
class Character():
def basics():
levelDict = {1: [ 25, 1, 6, 15, 2, 1, 5, 30],
2: [ 30, 1, 6, 15, 2, 2, 6, 90],
3: [ 35, 1, 8, 15, 3, 2, 7, 180],
4: [ 40, 1, 8, 15, 3, 3, 8, 300],
5: [ 45, 1, 10, 16, 4, 3, 9, 450],
6: [ 50, 1, 10, 16, 4, 4, 10, 630],
7: [ 55, 2, 12, 16, 5, 4, 11, 840],
8: [ 60, 2, 12, 16, 5, 5, 12, 1080],
9: [ 65, 2, 16, 16, 6, 5, 13, 1350],
10: [ 70, 2, 16, 17, 6, 6, 15, 1650],
11: [ 75, 3, 18, 17, 7, 6, 16, 1980],
12: [ 80, 3, 18, 17, 7, 7, 17, 2340],
13: [ 85, 2, 20, 17, 8, 7, 18, 2730],
14: [ 90, 2, 20, 17, 8, 8, 19, 3150],
15: [100, 2, 24, 18, 9, 8, 20, 3600],
16: [110, 4, 24, 18, 9, 9, 21, 4080],
17: [130, 4, 32, 18, 10, 9, 22, 4590],
18: [135, 4, 32, 18, 10, 10, 23, 5130],
19: [140, 3, 36, 18, 11, 10, 24, 5700],
20: [150, 3, 36, 19, 11, 11, 25, 6300]}
# As this is character creation, level will always be equal to 1, and xp always equal to 0
playerLevel = 1
playerXP = 0
# Grabs character's name, and then assigns appropriate values from the dictionary above to display.
charName = input("What is your characters name? ")
print("Your character's name is " charName ", and will start out at level one with the following stats:")
print("Hit Points: " str(levelDict[int(playerLevel)][0]))
statHP = levelDict[int(playerLevel)][0]
print("Damage: " str(levelDict[int(playerLevel)][1]) "d" str(levelDict[int(playerLevel)][2]))
print("Ability Points to Allocate: " str(levelDict[int(playerLevel)][3]))
statPoints = levelDict[int(playerLevel)][3]
print("Total Feats: " str(levelDict[int(playerLevel)][4]))
statFeats = levelDict[int(playerLevel)][4]
print("Total Base To Hit Modifier: " str(levelDict[int(playerLevel)][5]))
statHit = levelDict[int(playerLevel)][5]
print("Total Base damage Modifier: " str(levelDict[int(playerLevel)][5]))
statDamage = levelDict[int(playerLevel)][5]
print("Total Base AC: " str(levelDict[int(playerLevel)][6]))
statAC = levelDict[int(playerLevel)][6]
toNextLevel = (levelDict[int(playerLevel)][7]) - playerXP
print("You currently have: " str(playerXP) " experience and need: " str(toNextLevel) " to reach the next level.")
return playerLevel, statHP, statHit, statDamage, statPoints, statFeats, statAC, playerXP, toNextLevel, charName
'''
basics[0] = Level
basics[1] = Hit Points
basics[2] = To Hit Modifier
basics[3] = Damage Modifier
basics[4] = Total ability points
basics[5] = Total feats
basics[6] = Armor Class
basics[7] = player current xp
basics[8] = xp to next level
basics[9] = character name
'''
# This function focuses purely on assigning values to the three primary stats: Strength, Dexterity, and
# Constitution. While loops are set in place to ensure that no value is placed above 10, or any remaining points
# they player has left to allocate. Once completed, the information is displayed with their appropriate modifiers
# and the player is asked if they want to keep their setup, or redistribute.
def abilities(basics):
statPoints = basics[4]
print("You have " str(statPoints) " points to distribute between Strength, Dexterity, and Constitution.")
print("No single stat can be above 10 points")
answer = "no"
while answer == "no":
strengthStat = input("How many points do you want to put in Strength? ")
while int(strengthStat) > 10:
print("You can not allocate more than 10 points in any stat.")
strengthStat = input("How many points do you want to put in Strength? ")
remaining = int(statPoints) - int(strengthStat)
print("You have put " str(strengthStat) " points in Strength, and have " str(remaining) " points left.")
dexterityStat = input("How many points do you want to put in Dexterity?")
while int(dexterityStat) > remaining:
print("You only have " str(remaining) " points left")
dexterityStat = input("How many points do you want to put in Dexterity?")
remaining = remaining - int(dexterityStat)
print("You have put " str(dexterityStat) " points in Dexterity, and have " str(remaining) " points left")
conStat = input("How many points do you want to put in Constitution?")
while int(conStat) > remaining:
print("You only have " str(remaining) " points left")
conStat = input("How many points do you want to put in Constitution?")
strMod = int(int(strengthStat) / 2)
print("Your Strength: " str(strengthStat) " giving you a to Hit and Damage mod of " str(int(strMod)))
dexMod = int(int(dexterityStat) / 2)
print("Your Dexterity: " str(dexterityStat) " giving you a bonus to AC of " str(int(dexMod)))
conMod = int(conStat) * 5
print("Your Constitution: " str(conStat) " giving you bonus HP of " str(int(conMod)))
answer = input("Do you wish to keep these stats? (yes/no)").lower()
return strMod, dexMod, conMod, strengthStat, dexterityStat, conStat
# Grabs all the necessary information from the above functions, and commits them to a JSON file labeled with their
# character name.
# for testing purposes
# basics = basics()
# abilities = abilities(basics)
charWrite.py
class SaveModule:
def save(self, basics, abilities):
# Create an empty dictionary
characterFile = {}
featList = []
# basics[0] = Level
# basics[1] = Hit Points abilities[2] = Hit Point Modifier
# basics[2] = To Hit abilities[0] = To Hit Modifier
# basics[3] = Damage abilities[0] = Damage Modifier
# basics[4] = Total ability points
# basics[5] = Total feats
# basics[6] = Armor Class abilities[1] = Armor Class Modifier
# basics[7] = player current xp
# basics[8] = xp to next level
# basics[9] = character
# Fill the dictionary with required information
characterFile["name"] = basics[9]
name = basics[9]
characterFile["level"] = basics[0]
level = basics[0]
characterFile["hitpoints"] = basics[1] abilities[2]
hp = basics[1] abilities[2]
characterFile["total feats"] = basics[5]
tFeats = basics[5]
characterFile["hit"] = basics[2] abilities[0]
hit = basics[2] abilities[0]
characterFile["damage"] = basics[2] abilities[0]
damage = basics[2] abilities[0]
characterFile["ac"] = basics[6] abilities[1]
ac = basics[6] abilities[1]
characterFile["currentxp"] = basics[7]
xp = basics[7]
characterFile["nextlevel"] = basics[8]
nextLevel = basics[8]
characterFile["strength"] = int(abilities[3])
strength = int(abilities[3])
characterFile["dexterity"] = int(abilities[4])
dexterity = int(abilities[4])
characterFile["constitution"] = int(abilities[5])
constitution = int(abilities[5])
characterFile["player feats"] = featList
cFeats = featList
# apply a hidden counter, that will keep track of number of feats throughout level progression
characterFile["remaining feats"] = 2
remainingFeats = 2
# create the JSON file
file = open(basics[9] ".txt", "w", encoding="utf-8")
json.dump(characterFile, file, ensure_ascii=False, indent=2)
print("Your character has been created and saved.")
return name, level, hp, tFeats, hit, damage, ac, xp, nextLevel, strength, dexterity, constitution, cFeats, remainingFeats
Это работает, и, как вы можете видеть в конце, я пытаюсь передать переменные другим модулям для использования, обработки, обновления и отправки обратно для сохранения в другой функции в charWrite с именем update .
Но я не зашел так далеко. Я попытался импортировать charWrite в другие модули, затем используя information = charWrite.save(основы, способности), и я получаю сообщение об ошибке «основы не определены». Что это не так…это определено в модуле charCreation . Но даже импорт charCreation в модуль ничего не делает, чтобы помочь мне передать возвращаемые значения в функцию сохранения.
charFeats.py
import gameFeats
import charWrite
# import json
"""
This script is dedicated to pulling up helpful information on feats, as well as selecting them to be placed on the
character sheet.
"""
def feats():
# Open up character information
# charFile = open("Irixis.txt", "r", encoding="utf-8")
# charInfo = json.load(charFile)
# charFile.close()
# charLevel = charInfo["level"]
# remainingFeats = charInfo["remaining feats"]
# charStr = charInfo["strength"]
# charDex = charInfo["dexterity"]
# charCon = charInfo["constitution"]
# charfeatList = charInfo["player feats"]
#place all keys within a list for comparison later
information = charWrite.SaveModule.save(self, basics, abilities)
print(information)
featDict = gameFeats.featDict()[0]
featList = gameFeats.featDict()[1]
print("For a list of all the available feats, type 'list'")
print("For information on a specific feat, type 'help <feat>")
print("To choose a specific feat, type 'pick <feat>")
answer = input("Feat> ").lower()
while answer != 'back':
if answer == 'list':
for word in featList:
print(word, end=", ")
elif answer[:4] == 'help':
answer = answer[5:]
reqStat = featDict[0][answer]['stat']
featStatus = featDict[0][answer]['status']
level = featDict[0][answer]['requirements'][0]
reqStr = featDict[0][answer]['requirements'][1]
reqDex = featDict[0][answer]['requirements'][2]
reqCon = featDict[0][answer]['requirements'][3]
reqFeats = featDict[0][answer]['requirements'][4]
print(answer " (" reqStat ") (" featStatus ")")
print(featDict[0][answer]['desc'])
print("Prerequisites: " "Level: " str(level) " Strength: " str(reqStr) " Dexterity: " str(reqDex) " Constitution: " str(reqCon) " Required Feats: " reqFeats)
elif answer[:4] == 'pick':
if remainingFeats == 0:
print("You have no feat slots left to select a new feat.")
else:
answer = answer[5:]
level = featDict[0][answer]['requirements'][0]
reqStr = featDict[0][answer]['requirements'][1]
reqDex = featDict[0][answer]['requirements'][2]
reqCon = featDict[0][answer]['requirements'][3]
reqFeats = featDict[0][answer]['requirements'][4]
if answer in featDict and charLevel >= level
and charStr >= reqStr
and charDex >= reqDex
and charCon >= reqCon
and answer not in charfeatList:
print(answer " has been added to your character sheet.")
remainingFeats = remainingFeats - 1
playerFeats = charfeatList
playerFeats.append(answer)
print(playerFeats)
print("")
answer = input("Feat> ").lower()
return charLevel, remainingFeats, charStr, charDex, charCon, charfeatList
Я прокомментировал функцию загрузки для json в начале charFeats.py потому что я хочу получить переменные из charWrite и использовать этот модуль в качестве источника информации. Вы можете увидеть в charFeats, как я пытался вызвать information = charWrite .SaveModule.save(self, основы, способности) безрезультатно.
Я понимаю, что в конечном итоге я хотел бы, чтобы информация в функции сохранения использовалась в качестве переменных класса, но я не уверен, как передать их в класс.
Я чувствую, что здесь я ясен, как грязь, поэтому, если вам нужно разъяснение, я могу сделать все возможное, чтобы добавить его. У меня даже есть эти скрипты в моем git, если просмотр всего помогает.
Заранее спасибо.
Комментарии:
1. Если это в
charCreation
модуле, то этоcharCreation.basics
2. Нет. Требуемая информация (второй блок кода выше) находится в модуле с именем charWrite . Я пытался импортировать charWrite в другие модули и пытался charWrite.save() , charWrite.save(основы), charWrite.save(основы, способности) и только сейчас charWrite.basics() , но я получаю ту же ошибку
3. В какой строке какого кода вы получаете ошибку, как вы вызываете этот код для начала? почему вы не используете классы? почему вы отбрасываете return of
save(...,...)
? зачем переносить ваши символьные данные в виде кортежа? почему бы и нет:my_character = charWrite.save(basics, abilities)
? Использование кортежа для хранения ваших атрибутов символов плохо, потому что кортежи неизменяемы — вам нужно воссоздать их, чтобы что-то изменить — используя класс или (содрогание) список нет, никто не знает, сколько вещей в нем с неявным позиционным значением может быть лучше?4. Ошибка обнаружена в другом модуле. В этом случае charFeats . В этом модуле я сделал именно так, как вы предложили. Я создал функцию и сразу же попытался вызвать charWrite.save(основы, способности) и сохранить ее в переменной с именем «информация». Однако именно здесь я получаю сообщение об ошибке «основы не определены». Ошибка имеет смысл, потому что она определена еще в charCreation, а не связана с модулем charFeat. Я импортировал charWrite. Единственное, что я здесь не пробовал, это перекодировать charWrite, чтобы включить функцию сохранения в класс. Я попробую это и посмотрю, куда это меня приведет.
Ответ №1:
Прежде всего: отличная работа над learnign python, предоставив себе небольшой проект. Это отличный способ учиться.
Что касается вашего вопроса: было бы полезно, если бы вы опубликовали код, в котором действительно возникает ошибка. Но из вашего описания кажется, что вы не определяете переменную «основы» перед ее использованием.
в ‘do_create’ вы определяете ‘basics’ следующим образом: basics = charCreation.basics()
и то, что вы называете ‘charWrite.save (основы, способности)’
Это работает, потому что определены «основы». Похоже, вам не нужно определять «основы» в другом модуле.
Комментарии:
1. Я отредактировал свой исходный пост, чтобы включить все соответствующие модули для этой проблемы. С тех пор я пытался превратить все в классы, и до сих пор все работает так, как задумано, пока я не попытаюсь передать данные из метода сохранения в классе SaveModule в charFeats. Попытка сохранить информацию = charWrite . SaveModule.save(self, основы, способности) выдает ошибку. В данном случае это «имя self не определено». Где, как и раньше, без использования классов, это было «основы имени не определены».
2. это та же проблема, что и раньше.
3. Когда вы выполняете эту строку: информация = charWrite . SaveModule.save(self, основы, способности) ‘self’ еще не определен. Просто потому, что ‘self’ определено внутри класса или ‘basic’ определено внутри другой функции, это не означает, что оно определено в ‘feats()’.