简体   繁体   中英

How to pass reference of class A to class B in case of cyclic import while keeping type-hinting and auto-completion capabilities in Pycharm

In Python 3.7.2 I have two classes that are referencing each other.

I've looked at the question and answers in: Circular (or cyclic) imports in Python

and they don't answer the question of how to keep type-hinting and auto-completion capabilities when having a cyclic import. In order to allow Pycharm to auto-complete code, I am asking this question.

Class #1 represents ElasticSearch Server and imports class #2 as its member, in order to expose it as internal search capabilities.

Class #2 represents a bunch of search JSONs patterns and imports class #1 in order to define the type of an instance it receives of class #1. This allows Class #2 to run the GET\\POST methods that are defined in Class #1.

This looks something like this:

class SimplifiedElasticSearch

from framework.elk.search_patterns import SearchPatterns

class SimplifiedElasticSearch(object):
    ...
    ...

class SearchPatterns

from framework.elk.simplified_elastic_search import SimplifiedElasticSearch

class SearchPatterns(object):

    def __init__(self, es_server: SimplifiedElasticSearch):
        ...
        ...

You can see that both module import each other and an instance of class SimplifiedElasticSearch is passed to class SearchPatterns upon __ init __


This results in an import error

ImportError: cannot import name 'SimplifiedElasticSearch' from 'framework.elk.simplified_elastic_search'

To prevent the error, one option is to NOT import class SimplifiedElasticSearch, id remove the line

from framework.elk.simplified_elastic_search import SimplifiedElasticSearch

and write the code with auto-completion and type-hinting for the instance of SimplifiedElasticSearch that I pass to the class SearchPatterns


How can I keep the auto-completion and type hinting for such a case?

I suggest the following pattern. Using it will allow auto-completion and type hinting to work properly.

simplified_elastic_search.py

import search_patterns 

class SimplifiedElasticSearch(object):
    def __init__(self):
        pass

    def print_ses(self):
        print('SimplifiedElasticSearch')

if __name__ == '__main__':
    ses = SimplifiedElasticSearch()
    ses.print_ses()

    sp = search_patterns.SearchPatterns(ses)
    sp.print_sp()

search_patterns.py

import simplified_elastic_search 

class SearchPatterns(object):
    def __init__(self, ses):
        self.ses: simplified_elastic_search.SimplifiedElasticSearch = ses

    def print_sp(self):
        print('SearchPatterns-1-----------------')
        self.sp.print_sp()
        print('SearchPatterns-2-----------------')

You cannot import classes SimplifiedElasticSearch & SearchPatterns using this syntax

from simplified_elastic_search import SimplifiedElasticSearch  
from search_patterns import SearchPatterns

You cannot declare the type of parameter ses in class SearchPatterns's __ init __ method, but you can "cast" it this way:

def __init__(self, ses):
    self.ses: simplified_elastic_search.SimplifiedElasticSearch = ses

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM