Python 3.5类型提示动态生成的实例属性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 3.5类型提示动态生成的实例属性相关的知识,希望对你有一定的参考价值。

我想为动态生成的对象属性添加Python 3.5类型提示,以便IDE正确地自动完成它们。这里的“动态”是指在类创建过程中或在__init__或任何其他方法中不存在该属性。

例如。有没有办法通过评论或其他技巧添加这些?如果不是,我可以回退添加虚拟类属性。

例::

 class Request:
      """Example HTTP request object.

      We have `get_user()`  but we do not declare it anyhere.
      """

 ...


 # Pyramid's way of plugging in methods and properties to request, enabled addon capabilities for the framework
 # adds Request.user - done in different part of application lifecycle, not during class creation
 config.add_request_method(auth.get_user, 'user', reify=True)

目标是使这项工作能够使PyCharm和其他IDE完成此属性。

答案

在Python 3.6+中,您可以使用类级别类型提示 - 这些提示不会在类中生成属性。即

class Request(_Request):
    user: Optional[User]

这不会在类中创建属性,只会创建注释。

>>> Request.user
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Request' has no attribute 'user'

>>> Request.__annotations__
{'user': typing.Union[foo.User, NoneType]}

在Python 3.5中,可以创建一个返回非数据描述符的函数(即没有__set__的描述符);这将被一个实例属性覆盖,但它带来一些最小的运行时开销 - 描述符将从__dict__获取并检查它是否定义了__set__插槽 - 即使是所有读取。它可能看起来像

class Request(_Request):
    user = typed(User)

其中typed定义为

def typed(type: Type[T]) -> T:
    ... return a dummy non-data-descriptor...

这应该足以让PyCharm正确地推断出类型。

另一答案
  • 我将真正的类分类
  • 我在课堂上添加了人造__type_hinting__方法
  • 我使用这个类而不是真正的类作为参数类型提示 class Request(_Request): """ HTTP request class. This is a Pyramid Request object augmented with type hinting information for Websauna-specific functionality. To know more about request read also * py:class:`pyramid.request.Request` documentation * py:class:`webob.request.Request` documentation Counterintuitively, this request is also available in non-HTTP applications like command line applications and timed tasks. These applications do not get request URL from a front end HTTP webserver, but a faux request is constructed pointing to the website URL taken from ``websauna.site_url`` setting. This is to allow similar design patterns and methodology to be applied in HTTP and non-HTTP applications. By setting variables in ``__type_hinting__()`` based on arguments types allows IDEs to infer type information when you hint your views as:: from websauna.system.http import Request def hello_world(request: Request): request. # <-- When typing, here autocompletion kicks in. """ def __type_hinting__(self, user: Optional[User], dbsession: Session, session: ISession, admin: Admin, registry: Registry): """ A dummy helper function to tell IDEs about reify'ed variables. :param user: The logged in user. None if the visitor is anonymous. :param dbsession: Current active SQLAlchemy session :param session: Session data for anonymous and logged in users. :param admin: The default admin interface of the site. Note that the site can have several admin interfaces for different purposes. :param registry: Pyramid registry's. E.g. :py:attr:`pyramid.registry.Registry.settings` for reading settings and :py:meth:`pyramid.registry.Registry.notify` for sending events. """ self.user = user self.dbsession = dbsession self.session = session self.admin = admin self.registry = registry

以上是关于Python 3.5类型提示动态生成的实例属性的主要内容,如果未能解决你的问题,请参考以下文章

python 3.5代码中的变量需要类型注释

python 3.5+中的类型提示克隆函数

Python 使用省略号或无 + 浮点类型提示未分配属性

在 Python 中动态定义新的实例属性 [重复]

原型对象

python对象的创建和实例的生成次数