超级对象的'__init__'描述符需要参数。

27

我正在尝试用Python制作面向对象的文本游戏,并尝试实现我的第一个属性和装饰器。使用书籍'Python 3面向对象编程'中的第5章,我试图使用讨论的示例和概念来设置Game对象的“current_room”属性:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''
    def __init__(self):
        print("Accessing the FirstRoom __init__ method.")
        super.__init__()


class SecondRoom(Room):
    ''' Just some other room.'''
    def __init__(self):
        print("Accessing the SecondRoom __init__ method.")
        super.__init__()


class Game(object):
    ''' Creates a new game.'''
    current_room = None # Class-level definition of this property.

    def __init__(self):
        print("Created a new Game object.")
        self.current_room = FirstRoom()

    @property
    def current_room(self):
        ''' Returns the current position of the actor.'''
        print("Getting the _current_room attribute for the Game object.")
        return self._current_room

    @current_room.setter   
    def set_room(self, new_room):
        ''' Sets the current_room property of the Game object.'''
        print("Setting the _current_room attribute for the Game object.")
        self._current_room = new_room

然而,当我运行此代码时,我得到了以下输出:
>>> g = Game()
Created a new Game object.
Accessing the FirstRoom __init__ method.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/drew/Desktop/test.py", line 27, in __init__
    self.current_room = FirstRoom()
  File "/home/drew/Desktop/test.py", line 11, in __init__
    super.__init__()
TypeError: descriptor '__init__' of 'super' object needs an argument

我需要在代码中添加什么才能使这个语法生效? 我需要明确定义“current_room”属性的描述符吗?[至少书中没有提到任何关于描述符的内容,就像你在这里找到的Python Descriptors Demystified一样。]

7
你需要实际调用 super - user2357112
可能是如何从子类调用基类的__init__方法?的重复问题。 - R Sahu
看起来语法super().init()和将self.current_room = FirstRoom()更改为self._current_room = FirstRoom()修复了下一个错误。谢谢! - Automatic Bazooty
@RSahu 我不认为这个问题是重复的(至少不是那个问题)。事实上,OP的问题是没有调用super,而你链接的问题确实调用了super,产生的错误也非常不同。 - Bakuriu
3个回答

107

使用super().__init__()代替super.__init__()


1
非常感谢,你真是个宝贝。 - Michael Oshosanya

0

超级错误实际上是因为在调用super之前放置了print语句,以下代码可以正常工作:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''

    def __init__(self):
        super().__init__()
        print("Accessing the FirstRoom __init__ method.")



class SecondRoom(Room):
    ''' Just some other room.'''

    def __init__(self):
        super().__init__()
        print("Accessing the SecondRoom __init__ method.")

你需要学习如何使用@property等内容。

Python属性文档

从文档中可以看到,一定要将附加函数命名为与原始属性相同的名称

class Game(object):
    ''' Creates a new game.'''
    current_room = None  # Class-level definition of this property.

def __init__(self):
    print("Created a new Game object.")
    self._current_room = FirstRoom()

@property
def current_room(self, room): 
    ''' Returns the current position of the actor.'''
    print("Getting the _current_room attribute for the Game object.")
    return self._current_room


@current_room.setter # same function name as the property.
def current_room(self, new_room):# same name  as the property
    ''' Sets the current_room property of the Game object.'''
    print("Setting the _current_room attribute for the Game object.")
    self._current_room=new_room  

是的,使用Python 3.4.0。 - Automatic Bazooty
没问题。看一下文档,里面有一些很好的@property等工作的示例。 - Padraic Cunningham

0

这里是可用的代码:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''
    def __init__(self):
        print("Accessing the FirstRoom __init__ method.")
        #super.__init__()
        super(FirstRoom, self).__init__()


class SecondRoom(Room):
    ''' Just some other room.'''
    def __init__(self):
        print("Accessing the SecondRoom __init__ method.")
        super(SecondRoom, self).__init__()
        #super.__init__()


class Game(object):
    ''' Creates a new game.'''
    _current_room = None # Class-level definition of this property.

    def __init__(self):
        print("Created a new Game object.")
        self._current_room = FirstRoom()

    @property
    def current_room(self):
        ''' Returns the current position of the actor.'''
        print("Getting the _current_room attribute for the Game object.")
        return self._current_room

    @current_room.setter   
    def set_room(self, new_room):
        ''' Sets the current_room property of the Game object.'''
        print("Setting the _current_room attribute for the Game object.")
        self._current_room = new_room

当运行时:

>>> g = Game()
Created a new Game object.
Accessing the FirstRoom __init__ method.
Accessing the Room __init__ method.
>>> 

希望这能对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接