3
class Avatar:

    def __init__(self, HP=100, damage=10, defends=10, magic=5):
        self.__hp = HP
        self.__dam = damage
        self.__def = defends
        self.__mag = magic

    def check_hasattr(self):
        print hasattr(Avatar,'__hp')

warrior = Avatar(99,9,9,4)
Avatar.check_hasattr(warrior)

有人知道为什么print声明False在我期望的时候返回True吗?

4

2 回答 2

7

你有两个问题:

  1. 双下划线属性名称调用"name mangling",因此 eg__hp变为_Avatar__hp(参见例如关于继承的样式指南)。
  2. check_hasattr您检查属性时Avatarself,而不是实例

这会起作用:

class Avatar:

    def __init__(self, HP=100, damage=10, defends=10, magic=5):
        self.__hp = HP
        self.__dam = damage
        self.__def = defends
        self.__mag = magic

    def check_hasattr(self):
        print hasattr(self, '_Avatar__hp')

但是,没有必要保护对这些属性的访问(如果有,您应该使用 a@property而不是名称修饰);参见例如Python 名称修改

另请注意,Class.method(instance)可以重写为instance.method(). 但是,在这种情况下,最简单的方法是完全删除该方法并调用hasattr(warrior, '_Avatar__hp').

于 2015-05-13T08:22:55.347 回答
1

您的代码不起作用,因为您正在检查该类Avatar是否具有属性__hp,它没有它,只有实例具有它,因为该属性是在__init__. 换句话说,hasattr应该在selforavatar对象上调用,而不是在Avatar类上。

此外,双下划线在 python 中具有特殊含义,它破坏了名称,因此在无法直接访问的意义上是“私有的”。这意味着检查实例是否具有该属性__hp将不起作用(您应该_Avatar__hp改为检查)

我更改了您的代码以简化和删除没有太大意义的内容:

class Avatar:
    def __init__(self,HP=100):
        self._hp = HP

>>> avatar = Avatar()
>>> hasattr(avatar, '_hp')
True

注意:如果您创建 Avatar 的实例avatar = Avatar(),您应该直接在对象上调用方法avatar.mymethod(),而不是Avatar.mymethod(avatar)

于 2015-05-13T08:17:24.430 回答