【问题标题】:Call property getter, setter, deleter - Python调用属性获取器、设置器、删除器 - Python
【发布时间】:2014-03-04 20:49:55
【问题描述】:

我收到错误“类型错误:'locationTile' 在尝试调用其 fdel() 方法时不是可调用对象。代码:

class GamePlayLocationTiles(object):
    """The stuff needed for game play"""
    _locationTiles = []

    def locationTiles():
        doc = "property locationTiles's doc string"
        def fget(self):
            return self._locationTiles[0]
        def fset(self, value):
            self._locationTiles = value[0]
        def fdel(self):
            del self._locationTiles[0]
        return locals()  # credit: David Niergarth
    locationTiles = property(**locationTiles())

    def __init__(self):
        self.fill_location_tiles_list()

不同的模块:

import game_play_model

class GamePlayController:
    """perform operations on the game_play_model"""

    def __init__(self):
        self.the_game_location_tiles = game_play_model.GamePlayLocationTiles()
        self.shuffle_location_tiles()


    def shuffle_location_tiles(self):
        self.the_game_location_tiles.locationTiles().fdel() //this line causes the error

def main():
    the_game_play_controller = GamePlayController()

if __name__ == '__main__':
    main()

只是尝试删除它作为使用 getter、setter、deleter 访问私有变量的测试。

【问题讨论】:

    标签: python getter-setter


    【解决方案1】:
    def shuffle_location_tiles(self):
        del self.the_game_location_tiles.locationTiles
    

    不应直接调用fdel 函数。当实例尝试删除属性时,它将为您调用。

    例如,

    class Foo(object):
        def x():
            def fget(self):
                """I'm the 'x' property."""
                return self._x
    
            def fset(self, value):
                self._x = value
    
            def fdel(self):
                print('deleting x')
                del self._x
            return locals()
        x = property(**x())
    
        def __init__(self):
            self._x = None
    
    
    c = Foo()
    del c.x
    # deleting x
    

    self.the_game_location_tiles.locationTiles() 引发错误

    "Type error: 'locationTile' is not a callable
    

    因为self.the_game_location_tiles.locationTiles 调用fget 并返回值self._locationTiles[0]。该值恰好不可调用。

    您可以使用GamePlayLocationTiles.locationTiles 访问该属性本身,并调用fdel

    GamePlayLocationTiles.locationTiles.fdel(self.the_game_location_tiles)
    

    但是当你可以只使用语句时,没有理由这样做

    del self.the_game_location_tiles.locationTiles
    

    【讨论】:

    • 这是答案,谢谢。我尝试在我的 fdel 等代码中从 getter、setter、deleter 中删除 [0],因此它会删除整个列表,而不仅仅是一个成员,现在 fdel() 方法内部有一个错误,说 _locationTiles 是只读的.所以我可以得到它但不能删除它。你知道为什么吗?
    • 这是一个包含 setter、getter、deleter 的列表。你不能删除这样的列表。现在可以了。我将其更改为:'def fdel(self): del self._locationTiles[0:len(self._locationTiles)]' 谢谢 :)
    • 啊,简直就是实例不能删除类属性,(至少不是这样)
    • 哦,与我想象的略有不同的原因!感谢您提供所有信息!
    【解决方案2】:

    使用property 的意义在于你不是直接使用函数,而是使用常见的 Python 习惯用法来获取/设置/删除。

    在这种情况下,您不会调用self.the_game_location_tiles.locationTiles().fdel(),而是调用del self.the_game_location_tiles.locationTiles,这将调用您的fdel() 方法。

    获取和设置也是如此:

    • self.the_game_location_tiles.locationTiles 将使用您的 fget
    • self.the_game_location_tiles.locationTiles = y 将使用您的 fset

    【讨论】:

      【解决方案3】:
      def locationTiles():
          doc = "property locationTiles's doc string"
          def fget(self):
              return self._locationTiles[0]
          def fset(self, value):
              self._locationTiles = value[0]
          def fdel(self):
              del self._locationTiles[0]
          return locals()  # credit: David Niergarth
      
      locationTiles = property(**locationTiles()) # This redefines locationTiles to a variable
      

      我看到你有一个函数和一个变量都被赋予了相同的名称。这可能会导致执行问题。当您尝试引用函数 locationTiles() 时,Python 将其视为变量 locationTiles

      def shuffle_location_tiles(self):
          self.the_game_location_tiles.locationTiles().fdel() //this line causes the error
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      相关资源
      最近更新 更多