问题标签 [python-descriptors]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
108 浏览

python - 是否有一种内置方法可以使用 CPython 内置函数使任意可调用行为表现为未绑定的类方法?

在 Python 2 中,可以将任意可调用对象转换为类的方法。重要的是,如果 callable 是用 C 实现的 CPython 内置,您可以使用它来创建用户定义类的方法,这些方法本身就是 C 层,调用时不调用字节码。

如果您依赖 GIL 提供“无锁”同步,这有时会很有用;由于 GIL 只能在操作代码之间交换,如果代码的特定部分中的所有步骤都可以推送到 C 中,则可以使其以原子方式运行。

在 Python 2 中,您可以执行以下操作:

在 Python 3 中,不再有未绑定的方法类型,并且types.MethodType只接受两个参数并只创建绑定方法(这对于 Python 特殊方法(如__len__,__hash__等)没有用处,因为特殊方法通常直接在类型上查找,不是实例)。

在 Py3 中是否有一些我缺少的方法来实现这一点?

我看过的东西:

  1. functools.partialmethod(似乎没有 C 实现,所以它不符合要求,并且在 Python 实现和比我需要的更通用的用途之间,它很,在我的测试中大约需要 5我们,而直接约 200-300 ns Python 定义或attrgetter在 Py2 中,开销增加了大约 20 倍)
  2. 试图使attrgetter之类遵循非数据描述符协议(不可能的 AFAICT,不能在 a__get__等中进行猴子补丁)
  3. 试图找到一种方法来子类化attrgetter给它一个__get__,但当然,__get__需要以某种方式委托给 C 层,现在我们回到了我们开始的地方
  4. (特定于attrgetter用例)__slots__首先使用使成员成为描述符,然后尝试以某种方式从数据的结果描述符转换为跳过绑定的最后一步并将实际值获取为使其可调用的东西的东西所以真正的价值检索被推迟了

我不能发誓我没有错过任何这些选项。任何人有任何解决方案?允许完全骇客;我知道我在这里做病态的事情。理想情况下,它应该是灵活的(让您从 a class、Python 内置函数(如hexlen等)或任何其他未在 Python 层定义的可调用对象中创建行为类似于未绑定方法的东西)。重要的是,它需要附加到类,而不是每个实例(既可以减少每个实例的开销,也可以为 dunder 特殊方法正常工作,这些方法在大多数情况下会绕过实例查找)。

0 投票
2 回答
301 浏览

python - Python 属性和描述符

我一直在阅读Descriptor HowTo Guide中的描述符,我对这句话感到困惑:

如果实例的字典中有一个与数据描述符同名的条目,则数据描述符优先。

字典如何包含两个具有相同名称的项目(一个普通条目和一个数据描述符)?或者是描述符的属性没有存储在__dict__

0 投票
2 回答
198 浏览

python - 从“descriptors howto”文章中理解描述符示例

我试图围绕描述符的概念来思考,但最近我没有成功。这篇关于如何描述的文章确实有帮助,同时也让我感到困惑。我在这个例子中苦苦挣扎,为什么m.x打电话def __get__(self, obj, objtype):

我相信我为此苦苦挣扎的原因是因为我对文章中的以下陈述感到困惑

调用的细节取决于 obj 是对象还是类。对于物体来说,机器在object.__getattribute__() 其中转化b.xtype(b).__dict__['x'].__get__(b, type(b))。该实现通过优先链进行工作,该优先链赋予数据描述符优先于实例变量,实例变量优先于非数据描述符, __getattr__()如果提供,则分配最低优先级

我不确定作者在这里所说的对象或类是什么意思。对象是否意味着类的实例?我知道,当我们在instance.var内部执行 python时instance.__dict__["var"],如果未找到,则它会执行class.__dict__["var"]。在那个概念之后,我有点失去了它。谁能解释一下这个例子是如何工作的。定义是如何def __get__(self, obj, objtype):被调用的m.x。如果有人能解决这个问题,我将不胜感激。

0 投票
2 回答
1631 浏览

python - 为什么@staticmethod 没有跨类保留,而@classmethod 是?

采用以下示例脚本:

当我使用 Python 2.7.11 运行此脚本时,我得到:

似乎 @classmethod 装饰器在类中保留,但 @staticmethod 不是。

Python 3.4 的行为符合预期:

为什么 Python2 不保留 @staticmethod,是否有解决方法?

编辑:从班级中抽出两个(并保留@staticmethod)似乎可行,但这对我来说仍然很奇怪。

0 投票
0 回答
73 浏览

python - 在 Python 中模拟类型

我正在开发一个从卡中读取字节码的智能卡应用程序。

我想要一个<A>Field()应该表示保存数据的字段的类,<type 'A'>用字节码值实例化,我想尽可能自然地操作它。

我想到了这样的事情:

所以我可以使用如下:

我知道这是可以做到的,因为我已经看到了这个概念的实现。但他们会降到 C 级来实现它。有没有更简单的纯 python 方式来做到这一点?我怎样才能做到这一点?

0 投票
2 回答
16980 浏览

python - How can I get the attribute name when working with descriptor protocol in Python?

The descriptor protocol works fine but I still have one issue I would like to resolve.

I have a descriptor:

This is subclassed:

And then used is a model class:

So far, so good, this works just as expected.

The only issue I have here is that we have to give a field name every time a field is declared. e.g. "country_code_2" for the country_code_2 field.

How would it be possible to get the attribute name of the model class and use it in the field class?

0 投票
1 回答
523 浏览

python - 如何在子类中使用描述符的装饰器

我想知道是否可以在子类中使用描述符的装饰器。

当然,这不起作用,因为my_attr在 的类定义中未定义B

接下来我尝试了:

但是,这种方法会调用描述符__get__方法(instance_obj参数为None),因此会触发测试异常。要访问装饰器,可以检查是否instance_obj返回None描述符本身:

有用!但这是合理的还是有办法在 的类定义中使用装饰器B

0 投票
2 回答
629 浏览

python - 使用 cached_property 捕获异常

我正在尝试使用 https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76 来decorator捕获cached_property 异常

https://pypi.python.org/pypi/cached-property

我想做如下简单的事情,但这不起作用

我对此的破解是执行以下操作。有人可以建议我一个更好的方法。还有我如何将例外列表传递给这个my_cached_decorator

0 投票
2 回答
239 浏览

python - 如何装饰一个类并使用描述符来访问属性?

我正在尝试掌握(开始;))以了解如何在 Python 3 上正确使用装饰器和描述符。我想出了一个想法,我试图弄清楚如何对其进行编码。

我希望能够创建一个用某些“函数” B或“类” B装饰的类A,它允许我在将A上的属性声明为某种类型的组件并在 A 上分配值之后创建A的实例魔法功能。例如: __init__

组件化是允许我声明类 Vector的某些“函数B ”或“B 类” 。我声明xy是这样的组件(浮点数)

我的想法是能够做到这一点:

但主要目标是我想为每个标记的组件(浮动)属性执行此操作:

我的想法是创建一个装饰器@componentized来覆盖__getattr____setattr__魔术方法。排序这样的:

它有点奏效,但我认为我不太明白发生了什么。因为当我尝试进行分配并覆盖__setattr__魔术方法时,即使我正在实例化类,它也会被调用。以下示例中的两次:

我怎么能实现这种行为?

提前致谢!如果需要更多信息,请随时询问!

编辑:

按照@Diego的回答,我设法做到了:

并且有一个像这样的类Vector

它的行为就像我想要的那样,但我仍然不知道如何实现:

Vector类中以某种方式订阅float 类型的xy,因此当我在代码上执行#EMPHASIS LINE(在我硬编码特定类型的行中)时,我可以检查是否有人将值赋给x和/或Vector实例的y是我定义它的类型:

所以我尝试了这个(一个组件(描述符)类):

像描述符一样使用组件,但我无法设法解决该类型。我试图做一个数组来保存valtype,但后来不知道如何从装饰器__setattr__方法中获取它。

你能指出我正确的方向吗?

PS:希望你们理解我想要做的事情并帮助我。提前致谢

解决方案

好吧,使用@Diego 的答案(我将接受)和一些解决方法来满足我的个人需求,我设法做到了这一点:

装饰器(组件化)

组件(描述符类)

(代码注释是不言自明的)

通过这个设计,我可以实现我想要的(如上所述)谢谢大家的帮助。

0 投票
2 回答
571 浏览

python - Why does __get__ take an owner while __set__ and __delete__ do not?

From the Python data model documentation:

object.__get__(self, instance, owner=None)

Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). The optional owner argument is the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner.

This method should return the computed attribute value or raise an AttributeError exception.

PEP 252 specifies that __get__() is callable with one or two arguments. Python’s own built-in descriptors support this specification; however, it is likely that some third-party tools have descriptors that require both arguments. Python’s own __getattribute__() implementation always passes in both arguments whether they are required or not.

object.__set__(self, instance, value)

Called to set the attribute on an instance instance of the owner class to a new value, value.

Note, adding __set__() or __delete__() changes the kind of descriptor to a “data descriptor”. See Invoking Descriptors for more details.

object.__delete__(self, instance)

Called to delete the attribute on an instance instance of the owner class.

Why does __get__ take an owner while __set__ and __delete__ do not?

Does it mean that when a descriptor supplies both __get__ and __set__,

  • we can get an attribute no matter whether it belongs to an instance of the owner class or to the owner class,
  • we can set and delete an attribute when it belongs to an instance of the owner class but not when it belongs to the owner class?

My question is actually part of this one.