【问题标题】:Python Annotations: return type as an instancePython Annotations:作为实例返回类型
【发布时间】:2020-07-10 06:30:20
【问题描述】:

有没有办法让返回值知道它的类型应该属于某个isinstance

例如,def myfunction(...) -> instance[MyClass]: (这是一个非正式的语法,我只是举例我想要的语法是这样的)

这意味着它只接受属于MyClass的返回类型。


一个例子

下面给了我一个例子,让你更清楚我用它做什么。

考虑以下几点:

from typing import List, TypeVar, Union, Type


class Table:
    NAME: str

    def show_info(self):
        print(self.NAME)


class TableA(Table):
    NAME = 'A'

    def method_belong_a_only(self):
        print('a only')


class TableB(Table):
    NAME = 'B'

    def method_belong_b_only(self):
        print('b only')


class DBBase:
    Tables: List[Table]


class MyDB(DBBase):
    Tables = [TableA, TableB]

    def get_table(self, table_name: str) -> Union[Table, None]:
        table_list = [_ for _ in self.Tables if hasattr(_, 'NAME') and _.NAME == table_name]

        if not table_list:
            return None

        if len(table_list) > 1:
            raise ValueError('Table name conflict!')
        return table_list[0]()  # create an instance

然后如果我写以下内容,

db = MyDB()
ta = db.get_table('A')
ta.show_info()  # ok
# ta.  # IDE will show method, which belongs to Table only.
ta.method_belong_a_only()  # It still can run, but IDE show Cannot find reference 'method_belong_a_only' in Table|None

tb: TableB = db.get_table('B')  # It still can run, but IDE show ``Expected type 'TableA', got 'Optional[Table]' instead``
# tb.  # Now, It can show ``method_belong_b_only``

我不希望它(PyCharm IDE)向我显示警告,我希望它在 intelligence 上运行良好。

【问题讨论】:

    标签: python-3.x pycharm annotations pep


    【解决方案1】:

    你可以使用typing.TypeVarPEP484.type-aliases

    from typing import List, TypeVar, Union, Type
    
    
    T_Table = TypeVar('T_Table', bound=Table)
    
    
    class MyDB2(DBBase):
        Tables = [TableA, TableB]
    
        def get_table(self, t: Type[T_Table] = Table) -> Union[T_Table, None]:
            t_set = {cur_t for cur_t in self.Tables if cur_t.__name__ == t.__name__}
    
            if not t_set:
                return None
    
            table = t_set.pop()
            return table()   # create an instance
    
        def get_table_2(self, table_type_name: str) -> Union[T_Table, None]:
            t_set = {cur_t for cur_t in self.Tables if cur_t.__name__ == table_type_name}
    
            if not t_set:
                return None
    
            table = t_set.pop()
            return table()   # create an instance
    
    
    db = MyDB2()
    a = db.get_table(TableA)
    #  a = db.get_table(str)  # <-- Expected type 'Type[T_Table]', got 'Type[str]' instead
    a.method_belong_a_only()  # intellisense will work perfectly.
    
    b: TableB = db.get_table_2('TableB')  # This is another way, if IDE felt confused, you can tell him what the type it is.
    # b.  # intellisense will work perfectly.
    

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多