2015-12-11 17 views
6

Tôi muốn thêm gợi ý loại Python 3.5 cho các thuộc tính đối tượng được tạo động, để các IDE tự động hoàn thành chúng. Ở đây bởi "động" tôi có nghĩa là các thuộc tính không có mặt trong quá trình tạo lớp hoặc trong __init__ hoặc bất kỳ phương pháp nào khác.Python 3.5 loại gợi ý tự động tạo ra các thuộc tính ví dụ

Ví dụ: có cách nào để thêm các thông tin này thông qua nhận xét hoặc các thủ thuật khác không? Nếu không, tôi có thể dự phòng để thêm thuộc tính lớp giả.

Ví dụ ::

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) 

Mục đích là để làm cho công việc này để PyCharm và IDE khác sẽ hoàn thành thuộc tính này.

+0

Tôi nghi ngờ nó sẽ đòi hỏi rất nhiều nỗ lực để làm cho công việc này bất cứ nơi nào, nhưng trong thư viện thêm các phương pháp cho bạn. Nếu nó thêm các phương thức với các chú thích kiểu thích hợp được đính kèm, nó chỉ hoạt động. Có lẽ bạn nên gửi một lỗi yêu cầu tính năng trên Kim tự tháp? – Blckknght

Trả lời

1

Trong Python 3.6+ bạn có thể sử dụng gợi ý loại cấp lớp - se sẽ không tạo ra các thuộc tính trong lớp. I E.

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

Điều này sẽ không tạo thuộc tính trong lớp, chỉ chú thích.

>>> 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]} 

Trong Python 3.5 nó có thể làm cho một hàm trả về một mô tả phi dữ liệu (ví dụ: một bộ mô tả mà không__set__); điều này sẽ được ghi đè bởi một thuộc tính dụ nhưng nó đi kèm với một số chi phí tối thiểu thời gian chạy tối thiểu - trình mô tả sẽ được tìm nạp từ __dict__ và được kiểm tra nếu nó xác định vị trí __set__ - ngay cả đối với tất cả các lần đọc. Sau đó nó có thể trông giống như

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

nơi typed được định nghĩa là

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

này nên là đủ cho PyCharm để suy ra các loại một cách chính xác.

3
  • Tôi subclassed lớp thực

  • tôi thêm giả __type_hinting__ phương pháp trong lớp học của tôi

  • tôi sử dụng lớp này thay vì một thực như kiểu lập luận gợi ý

    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 
    
Các vấn đề liên quan