Evaluating forward references with typing.get_type_hints in Python for a class defined inside another method/class

huangapple go评论95阅读模式
英文:

Evaluating forward references with typing.get_type_hints in Python for a class defined inside another method/class

问题

我在调用具有字符串形式的前向引用的类的typing.get_type_hints()时遇到了问题。我的代码在不在函数内部定义时可以正常工作。我在下面的Python 3.10中复制了一个最小示例:

import typing
class B:
  pass
class A:
  some_b: "B" 
print(typing.get_type_hints(A)) # 打印 {'some_b': <class '__main__.B'>}
import typing
def func():
  class B:
    pass
  class A:
    some_b: "B" 
  print(typing.get_type_hints(A)) 
func() # NameError: name 'B' is not defined

这是否是预期行为?是否有任何方法可以解决这个问题,并确保字符串的前向引用在正确的范围内计算?

(Note: The code provided contains HTML entities for quotes and angle brackets, which may need to be corrected for proper execution in Python.)

英文:

I'm having trouble calling typing.get_type_hints() for classes that have forward references as strings. My code works with not defined inside of a function. I've reproduced a minimal example below in Python 3.10:

import typing
class B:
  pass
class A:
  some_b: "B" 
print(typing.get_type_hints(A)) # prints {'some_b': <class '__main__.B'>}
import typing
def func():
  class B:
    pass
  class A:
    some_b: "B" 
  print(typing.get_type_hints(A)) 
func() # NameError: name 'B' is not defined

Is this expected behavior? Is there any way to get around this, and make sure that forward references with strings get evaluated in the correct scope?

答案1

得分: 2

typing.get_type_hints 允许您通过 localns 参数明确传递本地命名空间以解析引用。

from typing import get_type_hints


def func():
    class A:
        some_b: "B"

    class B:
        pass

    print(get_type_hints(A, localns=locals()))


func()

输出:{'some_b': <class '__main__.func.<locals>.B'>}

请参阅 locals 文档。


顺便提一下:通过利用注解的延迟评估(PEP 563),您可以省略引号:

from __future__ import annotations
from typing import get_type_hints


def func():
    class A:
        some_b: B

    class B:
        pass

    print(get_type_hints(A, localns=locals()))
英文:

typing.get_type_hints allows you to explicitly pass the local namespace to use for resolving references via the localns parameter.

from typing import get_type_hints


def func():
    class A:
        some_b: "B"

    class B:
        pass

    print(get_type_hints(A, localns=locals()))


func()

Output: {'some_b': <class '__main__.func.<locals>.B'>}

See the docs for locals.


Side note: By utilizing postponed evaluation of annotations (PEP 563) you can omit the quotation marks:

from __future__ import annotations
from typing import get_type_hints


def func():
    class A:
        some_b: B

    class B:
        pass

    print(get_type_hints(A, localns=locals()))

huangapple
  • 本文由 发表于 2023年5月25日 00:23:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325603.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定