- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如果我有类似的问题,我深表歉意。我对python还不太熟悉,仍然习惯于oop。这就是说,如果这个群体中的许多善良的灵魂中有一个能够帮助我解决我的具体情况,或者把我引向已经被问到的类似问题的方向,尽管我想指出的是,google没有帮助,每个有类似错误的问题都有很大的不同,而且跨越了很多不同的项目,我很难找到解决办法——我将不胜感激。
假设我有一个名为“objects.py”的文件,用于存储我正在开发的基于文本的游戏的大部分类对象,在该文件中,我有一个名为“职业”的类。类“ocposition”保存用作“player”类修饰符的变量,稍后将对其进行更多描述。
其思想是,在根文件(即“root.py”)中,玩家将能够从玩家职业列表中进行选择,例如“巫师”或“骑士”,并使来自各个职业类的信息替换当前玩家变量信息。
“player.py”文件:
import objects
class Player(object):
nextlevel = 30
# 'nextlevel' is the gold required for a level up.
def __init__(self):
self.name = ''
self.level = 1
self.health = 1
self.stamina = 0
self.mana = 0
self.skills = {'str': 0, 'def': 0, 'dex': 0, 'int': 0, 'chr': 0, 'lck': 0}
self.spells = []
self.inventory = [{'armor': [objects.PrisonerRobes()], 'weapons': [objects.IronDagger()], 'bows': [], 'potions': [], 'misc': []}, objects.Gold(0), objects.Arrow(0)]
self.victory = False
class Occupation(object):
# Base class for all occupations / classes, e.g. 'knight' or 'wizard'.
classlist = ['warrior', 'knight', 'paladin', 'druid', 'warlock', 'wizard']
def __init__(self, name, hp, sp, mp, strv, defv, dexv, intv, chrv, lckv):
# The variable names of 'strv', 'defv', etc. stand for 'strength value', 'defence value', etc.
self.name = name
self.health = health
self.stamina = stamina
self.mana = mana
self.strv = strv #skill values
self.defv = defv
self.dexv = dexv
self.intv = intv
self.chrv = chrv
self.lckv = lckv
def __str__(self):
details = '{0}: HP: {1}, SP: {2}, MP: {3} // [STR: {4}, DEF: {5}, DEX: {6}, INT: {7}, CHR: {8}, LCK: {9}]'
return details.format(self.name, self.health, self.stamina, self.mana, self.strv, self.defv, self.dexv, self.intv, self.chrv, self.lckv)
class Warrior(Occupation):
def __init__(self):
super(Warrior, self).__init__('Warrior', 75, 50, 25, 12, 8, 12, 5, 8, 5)
from player import Player
import objects
def new_game():
while True:
print 'Only one class, and it is Warrior!'
print objects.Warrior()
classchoice = raw_input('Please type the full name of the class you wish to select.: ').lower()
playerclass = classchoice.title()
if classchoice != '':
characterclass = getattr(objects, playerclass)
player.health = characterclass.health
player.stamina = characterclass.stamina
player.mana = characterclass.mana
player.skills['str'] = characterclass.strv
player.skills['def'] = characterclass.defv
player.skills['dex'] = characterclass.dexv
player.skills['int'] = characterclass.intv
player.skills['chr'] = characterclass.chrv
player.skills['lck'] = characterclass.lckv
print 'You have chosen {0} as your class.'.format(characterclass.name)
confirm = raw_input('Is this correct? Type [Y] or [N] for yes/no respectively.: ').lower()
if confirm == 'y':
break
elif confirm == 'n':
continue
else:
print 'Not a valid keystroke!'
continue
line 48[in my original file]: player.health = characterclass.health
AttributeError: type object 'Warrior' has no attribute 'health'
最佳答案
我不同意查尔斯·梅里亚姆的回答我喜欢不同的课程。是的,一开始他们看起来都很像,只是有不同的数据但稍后您可以扩展它们以容纳多个功能。例如特殊修饰语,如战士的“愤怒”或巫师的“冥想”。
如果您将所有的鸡蛋放在一个字符类中,并且只是将不同的类表示为字符类的一个字符串属性,那么您以后将无法进行扩展事实上,我在文章的最后添加了rage
方法,看到了Charles Merriam的答案因为我使用了你的继承模型,所以我只需要修改这些行(原来我只想给你看作文。)
组成
在我展示这个继承的东西能做什么之前,我认为你做错了我认为您已经为您的职业创建了一个类继承模型,但后来迷失了方向,希望将其作为属性全部推送到Player类中。
更多的实际操作:你定义了一个职业类来保存属性(生命,法力,耐力,灵巧…)然后您创建了一个Player对象并使其完全相同,除了一些额外的Warrior
,items
属性。如果你花了所有这些努力来编码统计数据作为职业类的属性,你为什么要让玩家拥有特定的、独立的统计数据,就好像职业不存在一样?你不会的。
但具体怎么办我认为职业不能拥有物品。我们并没有像这样对职业进行编码,一个教学和思想体系拥有任何东西都有点奇怪。所以我想避免和球员一起继承职业。玩家不是职业的延伸,即使玩家可以拥有职业因此,我们想要的是一篇作文。
这时,您获取一个占领对象,并将其作为属性分配给一个玩家对象。
class CharClass(object):
#these stats have to be defined for EVERY occupation possible
#This can be used as a base class for players without defined classes yet
#by defining the default values of __init__
def __init__(self, name="Unknown", health=30, stamina=10, mana=10,
strv=1, defv=1, dexv=1, intv=0, chrv=0, lckv=0):
self.name = name
self.health = health
self.stamina = stamina
self.mana = mana
self.strv = strv #skill values
self.defv = defv
self.dexv = dexv
self.intv = intv
self.chrv = chrv
self.lckv = lckv
def __str__(self):
details = '{0}: HP: {1}, SP: {2}, MP: {3} \n'+\
'[STR: {4}, DEF: {5}, DEX: {6}, INT: {7}, CHR: {8}, LCK: {9}]'
return details.format(self.name, self.health, self.stamina, self.mana, self.strv,
self.defv, self.dexv, self.intv, self.chrv, self.lckv)
class Warrior(CharClass):
def __init__(self):
super(Warrior, self).__init__(health=100, stamina=50, dexv=20)
def __str__(self):
parentstring = super(Warrior, self).__str__()
return "You are a Warrior \n"+parentstring
class Player(object):
def __init__(self, charclass=CharClass(), items=[], spells=[], victory=False):
self.charclass = charclass #the generic class is the default one
self.items = items
self.spells = spells
newplayer = Player()
print newplayer
print newplayer.charclass
print
#graduating to a Warrior
newplayer.charclass = Warrior()
print newplayer
print newplayer.charclass
print
#there's a snag though. Every time now if you want to print or change Players health
#(or some other attribute) you'd have to spell all of this:
print newplayer.charclass.health
newplayer.charclass.health += 100
print newplayer.charclass.health
#this is because Player object contains a Warrior object in it and what you really change is that
#Warrior object and not the Player.
print type(newplayer.charclass)
<__main__.Player object at 0x000000000427A550>
Unknown: HP: 30, SP: 10, MP: 10
[STR: 1, DEF: 1, DEX: 1, INT: 0, CHR: 0, LCK: 0]
<__main__.Player object at 0x000000000427A550>
You are a Warrior
Unknown: HP: 100, SP: 50, MP: 10
[STR: 1, DEF: 1, DEX: 20, INT: 0, CHR: 0, LCK: 0]
100
200
<class '__main__.Warrior'>
victory
和
__getattr__
我们重写这些函数来截取特殊符号
__setattr__
(即
.
)和
self.attribute
的作用。我们让这些操作符设置或获取player类的属性,而不是设置或获取合成对象的属性!
class Player(object):
def __init__(self, charclass=CharClass(), items=[], spells=[], victory=False):
self.charclass = charclass
self.items = items
self.spells = spells
def __getattr__(self, attr):
return getattr(self.charclass, attr)
def __setattr__(self, attr, val):
if "charclass" in vars(self) and attr in vars(self.charclass):
self.charclass.__dict__[attr] = val
else:
self.__dict__[attr] = val
=
:
print newplayer.health
newplayer.health -= 50
print newplayer.health
200
150
self.charclass
和
charclass
。它们不是容易覆盖的函数。
__getattr__
更容易,只要player对象中没有同名的内容,它就会自动被调用。所以你要小心的是不要在player中添加同名的新属性。
__setattr__
函数中也会调用
__getattr__
。如果我们不检查,我们会得到一个错误。这就是
__setattr__
所做的;检查
__init__
是否向对象添加了
if "charclass" in vars(self)
属性。
__init__
属性,当我们尝试添加另一个属性时会发生什么即第二排:
charclass
?
charclass
将被调用,它将检查
items
中的
__setattr__
,它将看到它在那里,然后它将添加项到
charclass
而不是
self
!实际上,它会将属性添加到战士对象而不是玩家对象。
self.charclass
)。这就是
self
的意思。
self.__dict__[attr] = val
和
and attr in vars(self.charclass)
方法:
class Warrior(CharClass):
#this class basically just defines different default values than CharClass
def __init__(self):
super(Warrior, self).__init__(health=100, stamina=50, dexv=20)
def __str__(self):
parentstring = super(Warrior, self).__str__()
return "You are a Warrior \n"+parentstring
def rageON(self):
print "You are in a blood-rage +30 attack modifier"
self.stamina += 30
def rageOFF(self):
print "You have calmed down."
self.stamina -= 30
newplayer.rageON()
print newplayer.charclass
print "----------------------------------------------------------------------------------------"
newplayer.rageOFF()
print newplayer.charclass
You are in a blood-rage +30 attack modifier
You are a Warrior
Unknown: HP: 150, SP: 80, MP: 10
[STR: 1, DEF: 1, DEX: 20, INT: 0, CHR: 0, LCK: 0]
----------------------------------------------------------------------------------------
You have calmed down.
You are a Warrior
Unknown: HP: 150, SP: 50, MP: 10
[STR: 1, DEF: 1, DEX: 20, INT: 0, CHR: 0, LCK: 0]
关于python - 有关从子类中提取对象信息的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36756282/
我是一名优秀的程序员,十分优秀!