简体   繁体   English

如何打印子类的属性?

[英]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__接受xydesc参数,而您没有传递它们。 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? 为什么还要采用 xydesc参数来忽略它们呢?

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. 我认为您只想要Roomroom3实例,而不是子类。


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.

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