调用属性的获取器、设置器、删除器 - Python
我在尝试调用一个叫做 fdel() 的方法时,遇到了错误:“类型错误:'locationTile' 不是一个可调用的对象”。代码如下:
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 来访问一个私有变量,结果出现了这个错误。
3 个回答
0
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
def shuffle_location_tiles(self):
self.the_game_location_tiles.locationTiles().fdel() //this line causes the error
我注意到你有一个函数和一个变量,它们的名字是一样的。这可能会导致执行时出现问题。当你尝试调用函数locationTiles()时,Python会把它当作变量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
方法。
4
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
来访问这个属性,然后用
GamePlayLocationTiles.locationTiles.fdel(self.the_game_location_tiles)
来调用 fdel
,但其实没有必要这样做,因为你可以直接使用这个语句
del self.the_game_location_tiles.locationTiles