【问题标题】:Sending arguments to getter in python: Is this an acceptable solution?在 python 中向 getter 发送参数:这是一个可以接受的解决方案吗?
【发布时间】:2014-01-11 19:44:12
【问题描述】:

为了便于讨论,假设我想从dictionary 写入和读取值,但我想将一些字符串附加到字典键。我不想让用户进行字符串操作,而是想将其隐藏在 settergetter 方法中。这对 Python setter 方法没有问题,因为我可以发送一个包含可解析信息的列表。但是,它不适用于getter 方法,因为参数不能发送到getter。我已经制定了如下所示的解决方法,其中getter 返回一个接受参数并执行我想要的函数的函数。我只是想知道这个 Python 是否可以接受,或者我是否会后悔使用这种方法。

class tester(object):
    def __init__(self):
        self._dict = {}

    def _set(self,some_list):
        self._dict.update({some_list[0]+'_'+some_list[1]: some_list[2]})

    def _get(self):
        return self._func

    def _func(self,key1,key2):
        keys = key1+'_'+key2
        return self._dict[keys]

    props = property(_get, _set)

a = tester()
value = [1,2,3,4,5]
a.props = ('main_key','sub_key',value)
print(a.props('main_key','sub_key'))

我已经到处搜索了适合我需要的 settergetter 的使用方法,但我看到的只是人们断言 Python 不需要它们,我们都应该只是成年人并访问属性直接地。我找到的最接近的是question,但我发现我的解决方案更直接。

【问题讨论】:

  • 我不认为这本身有什么问题。而且由于它封装得很好,我真的看不出你有任何问题。恕我直言,这样做有点奇怪=)
  • 你也可以使用__getitem____setitem__
  • @Faust:我讨厌要求太高,但可以详细说明你的建议,或者给我举个例子吗?
  • @2cynykyl 我已经回答了给你一个例子。

标签: python properties getter getter-setter


【解决方案1】:

属性(或任何其他描述符)用于计算属性,即具有属性的语义但需要在设置和/或获取时进行一些计算的成员。通过“属性的语义”,我的意思是,从客户端的代码来看,这样写是有意义的:

something = obj.attribute

和/或

obj.attribute = something_else

一旦您必须将参数传递给 getter 或将多个参数传递给 setter,显然它没有 attribute 语义,因此您不能使用计算属性。解决方案很简单:使用明确的 getter/setter 对。

关于在 Python 中不需要 getter/setter 的要点是,对于任何具有属性语义的东西(但不是其他任何东西),如果当且何时,您总是可以将直接属性访问转为计算属性访问您需要它而不破坏客户端代码。这显然不是你的情况。

tl;dr:以你的方式滥用属性不是 pythonic,你最好使用显式的 getter 和 setter。

【讨论】:

  • 您可以将“多个参数传递给 setter”视为仅传递一个 tuple-valued 参数...
  • @EMS:你如何处理需要参数的吸气剂?-)
  • @brunodesthuilliers:我目前确实使用显式 getter 和 setter,但我被 property 的简洁/一致语法所吸引。我非常感谢您对直接属性和计算属性的描述。如果我理解正确,那么向“setter”发送参数就是作弊,这澄清了我对为什么gettersetter 灵活得多的困惑
  • @2cynykyl:属性的语法清晰且一致,正是因为它只做一件事。您的代码示例(您希望它的外观)非常令人困惑。所以,是的,我赞成这两个答案:你应该使用自定义方法或__setitem__
  • 好吧,一个setter(一个属性或其他描述符的setter)当然需要一个参数——你想要设置你的属性的值。 getter 显然不应该期待任何参数。还 set 和 get 应该尽可能对称 - 人们不会期望在将属性的值设置为列表或元组之后,获取相同的属性会返回一个可调用的参数少一个;)更严重的是:这是合法的 Python但它也尽可能地不符合标准。你的 API 应该是 set_value((key1, key2), value) and get_value((key1, key2))`。
【解决方案2】:

以下是使用__getitem____setitem__ 可以执行的操作的示例:

class tester(object):

    class Subelement(object):
        def __init__(self, obj, key):
            self.obj = obj
            self.key = key

        def __getitem__(self, subkey):
            return self.obj._dict[self.key + '_' + subkey]

        def __setitem__(self, subkey, value):
            self.obj._dict[self.key + '_' + subkey] = value

    def __init__(self):
        self._dict = {}

    def __getitem__(self, key):
        return Subelement(self, key)

【讨论】:

    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多