[英]How do you print an attribute of a subclass?
I am making a text based game and this is the file I am using to establishing the attributes of the rooms. 我正在制作一个基于文本的游戏,这是我用来建立房间属性的文件。 Whenever I try to test this file out by printing the room description of room3 (print Room3.desc) I receive the error: AttributeError: type object 'Room3' has no attribute 'desc' 每当我尝试通过打印room3的房间描述(打印Room3.desc)来测试该文件时,都会出现错误:AttributeError:类型对象'Room3'没有属性'desc'
class Room:
def __init__(self, x, y, desc):
self.x=x
self.y=y
self.desc=desc
class Room1(Room):
def __init__(self, x, y, desc):
super(Room1, self).__init__()
self.x=0
self.y=0
self.desc="""
A Metal Hallway
This place is dimly lit and cool
----------------------------------------------------
You stand in the middle of an intersection in a metal room.
There are blue glowing lamps lighting this area up. There
is a sign on the wall.
----------------------------------------------------
Obvious exits:East, North"""
class Room2(Room):
def __init__(self, x, y, desc):
super(Room2, self).__init__()
self.x=1
self.y=0
self.desc="""
Thacker's Main Control Room
This place is well lit and cool
----------------------------------------------------
There are multiple panels throughout with a variety of levers and buttons.
People stand in uniforms infront of computers, which are scattered throughout the room.
There is a glass window here revealing space.
Thacker is sitting here in the back of the room in a large chair.
----------------------------------------------------
Obvious exits:West"""
class Room3(Room):
def __init__(self, x, y, desc):
super(Room3, self).__init__()
self.x=0
self.y=1
self.desc== """
Large Hanger Bay
This place is well lit and cool
----------------------------------------------------
There are a variety of mobile suits here
----------------------------------------------------
Obvious exits:South"""
print("%s" % Room3.desc)
You're trying to access desc
via reference to the class itself, but desc is defined in the constructor, which means it's only available in instances of the class. 您正在尝试通过引用类本身来访问desc
,但是desc是在构造函数中定义的,这意味着它仅在类的实例中可用。
This points to a general problem with your code: you're defining subclasses of Room, when what you really want is to create instances of the class Room: 这指向您的代码的一个普遍问题:当您真正想要创建Room类的实例时,您正在定义Room的子类:
room1 = Room(0, 0, """A Metal Hallway...")
room2 = Room(1, 0, """Thacker's main control room...")
etc...
Your __init__
methods define attributes of instances, not of classes. 您的__init__
方法定义实例的属性,而不是类的属性。 If you had something like this: 如果您有这样的事情:
class Room3(Room):
desc = 'foo'
...
Then there would be such a thing as Room3.desc
. 然后会有诸如Room3.desc
这样的东西。 As it is, you would need something like this: 实际上,您将需要以下内容:
r = Room3(x, y, 'foo')
print(r.desc)
For more, study the tutorial, the section on Classes, at docs.python.org . 有关更多信息,请阅读docs.python.org上的教程,有关类的部分。
Room3.desc is an instance attribute rather than a class attribute. Room3.desc是实例属性,而不是类属性。 You can't access instance attributes on a class object - they don't exist there. 您无法访问类对象上的实例属性-它们在那里不存在。
You aren't using an instance of Room3, but the class, so you can't access the attribute that doesn't exist. 您不是使用Room3的实例,而是类的实例,因此您无法访问不存在的属性。 You can create a throwaway instance if you want to access the default instance attribute: 如果要访问默认实例属性, 可以创建一个一次性实例:
print Room3(None, None, None).desc
Also, your calls to your superclass init methods will fail in instance construction, because you aren't passing required arguments. 同样,对超类init方法的调用将在实例构造中失败,因为您没有传递必需的参数。
As cmd
says, desc
is not an attribute of the Room3
class object, it's an attribute of each Room3
instance . 正如cmd
所说, desc
不是Room3
类对象的属性,而是每个Room3
实例的属性。
I think the real problem here is that you don't want Room3
to be a subclass of Room
; 我认为这里的真正问题是您不希望Room3
成为Room
的子类; you just want an instance of Room
. 您只需要Room
一个实例 。 There's no code or attributes specific to Room3
, and it's hard to imagine you're going to be creating a bunch of Room3
instances. 没有特定于Room3
代码或属性,很难想象您将要创建一堆Room3
实例。
So what you probably want is this: 因此,您可能想要的是:
room3 = Room(1, 0, """blah blah""")
Now you can print room3.desc
and it will work fine. 现在,您可以print room3.desc
,它将正常工作。
Meanwhile, if you do want Room3
to be a class, there are a lot of problems with your design: 同时,如果您确实希望Room3
成为类,则您的设计存在很多问题:
def __init__(self, x, y, desc):
super(Room3, self).__init__()
self.x=0
self.y=1
self.desc== """…"""
First, that super
call is going to raise an exception, because Room.__init__
takes x
, y
, and desc
parameters, and you aren't passing them. 首先,该super
调用将引发异常,因为Room.__init__
接受x
, y
和desc
参数,而您没有传递它们。 You have to change it to super(Room3, self).__init__(x, y, desc)
. 您必须将其更改为super(Room3, self).__init__(x, y, desc)
。
But once you fix that, the base class is going to set self.x
, etc., just for you to immediately replace them with new values. 但是,一旦您解决了该问题,基类将设置self.x
等,只是为了您立即将它们替换为新值。 Why do this? 为什么这样 And why even take x
, y
, and desc
parameters just to ignore them? 为什么还要采用 x
, y
和desc
参数来忽略它们呢?
I think what you want is this: 我认为您想要的是:
def __init__(self):
super(Room3, self).__init__(0, 1, """…""")
This is actually a pretty common pattern (although not as common as in languages like C++ and Java), where you have a base class that holds some variables that can take arbitrary values, and subclasses that have specific values for some of those variables. 实际上,这是一个非常常见的模式(尽管不像C ++和Java这样的语言常见),在这里,您有一个基类,其中包含一些可以采用任意值的变量,以及子类,其中某些变量具有特定的值。
But, as I said, I don't think it's the pattern you want here. 但是,正如我所说,我认为这不是您想要的模式。 I think you just want a room3
instance of Room
, not a subclass. 我认为您只想要Room
的room3
实例,而不是子类。
Finally, to answer the question you directly asked, "How do you print an attribute of a subclass?", that's easy. 最后,回答您直接问的问题:“如何打印子类的属性?”,这很容易。 Just print it. 只需打印即可。 That's how duck typing works. 这就是鸭子打字的工作方式。 For example: 例如:
class Base(object):
def print_x(self):
print self.x
class Derived(Base):
def __init__(self, x):
self.x = x
base = Derived(3)
base.print_x()
print("%s" % Room3.desc)
desc
is an attribute of an instance of Room3, not of class Room3 itself. desc
是Room3实例的属性,而不是Room3本身的属性。 If you instanciate Room3, then you can access its attribute desc. 如果实例化Room3,则可以访问其属性desc。 Also be careful with your __init()__
as you have an extra =
另外,还要小心__init()__
因为您有一个额外的=
class Room3(Room):
def __init__(self, x, y, desc):
super(Room3, self).__init__()
self.x=0
self.y=1
self.desc== """
last line should be self.desc= """
最后一行应该是self.desc= """
Room3
class does not have the attribute desc
. Room3
类没有属性desc
。 Instances of that class do. 该类的实例可以。 So something like this would work: 所以这样的事情会工作:
room3 = Room3()
print(room3.desc)
self.desc== """
There is an extra =
. 有一个额外的=
。 And you must instantiate Room3
to access the desc
attribute. 并且您必须实例化Room3
才能访问desc
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.