【问题标题】:Is there an error in PythonDecoratorLibrary - Property Definition 3?PythonDecoratorLibrary - 属性定义 3 中是否有错误?
【发布时间】:2014-07-04 15:59:48
【问题描述】:

我尝试使用 PythonDecoratorLibrary 中的属性定义(示例 3)。 => https://wiki.python.org/moin/PythonDecoratorLibrary#Property_Definition

import sys
def property(function):
  keys = 'fget', 'fset', 'fdel'
  [...]

另外导入 sys 后出现此错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in Angle
  File "<stdin>", line 12, in property
TypeError: property() got an unexpected keyword argument 'doc'

第 12 行是:function(),因为 sys 导入 :)

我在 Windows 上的 python 版本是 3.4.1。

【问题讨论】:

  • 换一种说法只是删除属性函数定义,因为它是一个内置函数

标签: python python-3.x properties


【解决方案1】:

首先:这是一种丑陋的方式,它允许本地函数定义 3 个属性函数。

示例装饰器掩盖了property 内置,但随后仍尝试使用它来生成property 对象。哎呀。

您仍然可以通过以下方式访问原始内置:

import builtins

def property(function):
    keys = 'fget', 'fset', 'fdel'
    func_locals = {'doc':function.__doc__}
    def probe_func(frame, event, arg):
        if event == 'return':
            locals = frame.f_locals
            func_locals.update(dict((k, locals.get(k)) for k in keys))
            sys.settrace(None)
        return probe_func
    sys.settrace(probe_func)
    function()
    return builtins.property(**func_locals)

builtins module 允许您访问内置函数,即使本地名称已被覆盖。

我已更新 wiki 页面以反映这一点。

【讨论】:

  • 您建议使用哪些其他方式在 python3 中实现属性?我不认为 PythonDecoratorLibrary(示例 1)和内置属性装饰器是非常好的方法:)
  • @Paebbels:坚持使用property decorator syntax(例如@property,然后是@foo.setter,等等);从长远来看,使用广泛的最佳实践将导致代码更具可维护性和可读性,因为您不必不断重新学习在实施时认为更易读的任何替代方法。
【解决方案2】:

该示例依赖于内置的property 函数,同时也将自身命名为property

def property(function):
    keys = 'fget', 'fset', 'fdel'
    func_locals = {'doc':function.__doc__}
    def probe_func(frame, event, arg):
        if event == 'return':
            locals = frame.f_locals
            func_locals.update(dict((k, locals.get(k)) for k in keys))
            sys.settrace(None)
        return probe_func
    sys.settrace(probe_func)
    function()
    return property(**func_locals)  # This is supposed to be the built-in property

所以它最终调用自己(它不接受 doc 关键字参数),而不是内置的 property(它接受 doc 关键字参数)。所以是的,这个例子被打破了。它调用的函数property 应该命名为其他名称,或者它应该保存对内置property 的引用并在内部调用它。

编辑:使用builtins.property 显然比在屏蔽之前保存对property 的引用要好得多。所以就这样吧。

【讨论】:

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