Python3.5类型暗示动态生成的实例属性

Python3.5类型暗示动态生成的实例属性,python,pycharm,python-3.5,Python,Pycharm,Python 3.5,我想为动态生成的对象属性添加Python3.5类型的提示,以便IDE正确地自动完成它们。这里所说的“动态”是指属性在类创建过程中或在\uuuuu init\uuuu或任何其他方法中不存在 例如,有没有办法通过评论或其他技巧添加这些内容?如果没有,我可以回退添加虚拟类属性 例如: class Request: """Example HTTP request object. We have `get_user()` but we do not declare it an

我想为动态生成的对象属性添加Python3.5类型的提示,以便IDE正确地自动完成它们。这里所说的“动态”是指属性在类创建过程中或在
\uuuuu init\uuuu
或任何其他方法中不存在

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

例如:

 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能够完成此属性。

  • 我将真实类划分为子类

  • 我在我的类中添加了faux
    \uuuu type\u hinting\uuu
    方法

  • 我使用这个类而不是真正的类作为参数类型提示

    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 
    
    类请求(\u请求):
    """
    HTTP请求类。
    这是一个金字塔状的请求对象,添加了Websauna特定功能的类型提示信息。
    要了解有关请求的更多信息,请阅读
    *py:class:`pyramid.request.request`documentation
    *py:class:`webob.request.request`文档
    与直觉相反,该请求也适用于非HTTP应用程序,如命令行应用程序和定时任务。
    这些应用程序不会从前端HTTP Web服务器获取请求URL,但会构造一个伪请求,指向从“websauna.site\u URL”设置获取的网站URL。
    这是为了允许在HTTP和非HTTP应用程序中应用类似的设计模式和方法。
    通过基于参数在``类型``提示``中设置变量,类型允许IDE在提示视图时推断类型信息:
    从websauna.system.http导入请求
    def hello_world(请求:请求):
    
    请求。#在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]}
    
    其中键入的
    定义为

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

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

    我怀疑,除了为您添加方法的库之外,在任何地方都需要付出大量的努力才能使这项工作正常进行。如果它添加了带有正确类型注释的方法,它应该可以正常工作。也许您应该在Pyramid上提交一个功能请求错误?嗨,Mikko,我找不到关于
    \uuuuu type\u hinting\uuuuu
    的任何文档。我在哪里可以了解更多信息?我想任何方法都应该可以工作,只要它为IDE提供成员类型的“一些提示”。你能找到的唯一地方就是上面。然而,这是旧的和不相关的,因为现代Python解释器有变量注释,谢谢你的解释。
    def typed(type: Type[T]) -> T:
        ... return a dummy non-data-descriptor...