Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在包级别使用类型注释_Python_Django_Python 3.x_Type Hinting - Fatal编程技术网

Python 在包级别使用类型注释

Python 在包级别使用类型注释,python,django,python-3.x,type-hinting,Python,Django,Python 3.x,Type Hinting,我想在IDE中使用注释来实现更好的自动完成,也许以后在自动测试中使用类型测试。但是,如何在不引入大量额外代码的情况下向许多方法添加类型注释呢 例如,假设您有一个使用Django框架的大型代码库,包括大约200个带有request参数的方法;添加200次类型注释会使代码膨胀 我目前的想法是在包级别包括类型注释:在setup.py(或其他地方)。我定义了一个规则,它说“每次使用变量request,它的类型都是django.http.HttpRequest”。对于名称为request的变量指向不同类型

我想在IDE中使用注释来实现更好的自动完成,也许以后在自动测试中使用类型测试。但是,如何在不引入大量额外代码的情况下向许多方法添加类型注释呢

例如,假设您有一个使用Django框架的大型代码库,包括大约200个带有
request
参数的方法;添加200次类型注释会使代码膨胀

我目前的想法是在包级别包括类型注释:在
setup.py
(或其他地方)。我定义了一个规则,它说“每次使用变量
request
,它的类型都是
django.http.HttpRequest
”。对于名称为
request
的变量指向不同类型的边缘情况,应该进行显式注释,但这些注释很少

如何实现这一点?是否有其他方法可以实现总体目标?

您可以使用自定义(未经测试):

默认情况下,此中间件将影响所有URL。对于不希望检查请求类型的少数URL,请在URL.py的相应行中添加一个参数:

url(r'^foo/$', views.your_view, require_http_request=False)
并将特定注释放入
my_view()

的定义中。您可以使用自定义(未经测试):

默认情况下,此中间件将影响所有URL。对于不希望检查请求类型的少数URL,请在URL.py的相应行中添加一个参数:

url(r'^foo/$', views.your_view, require_http_request=False)

并将特定注释放入
my_view()

的定义中。如果我的理解正确,这听起来像是存根文件的用例,如中所述:

存根文件是包含类型提示的文件,只供类型检查器使用,不在运行时使用

存根文件基本上满足了将代码与类型注释分离的要求,从而避免了复杂类型提示的膨胀和混淆效果。它们的前缀为
.pyi
,如果由
IDE
实现的类型检查器想要符合
PEP 484
,则必须始终由类型检查器检查(如果存在)

它们基本上由带注释的函数签名组成,其主体包含一个省略号


一种方法是使用helper函数写出
.pyi
,或者至少写出大部分内容。可能有很多方法可以做到这一点,而哪种方法最好可能是另一个问题

作为一个这样做的示例,我将写出一种方法来注释
inspect
模块中的每个函数,该模块的参数名为
object
,并且不以下划线开头。我正在输入这个特定的模块,因为我还将使用它来识别函数并获取它们的签名

inspect
模块中,我将使用、和函数

# gets members of inspect module {member_name: member_type} dict.
members = getmembers(inspect)  

# loop through members
for name, type in members:

    # grab functions that don't start with an underscore  
    if isfunction(type) and not name.startswith('_'):

        # grab its signature and
        # check if it has a parameter named object
        sig = signature(type)  
        if 'object' in sig.parameters:

            # add the annotation to the object parameter
            param = sig.parameter['object']
            s = sig.replace(parameters = [param.replace(annotation="object")])

            # here you normally write to .pyi file
            print('def {0} {1}: ...'.format(name, s))  
该逻辑可以扩展到
方法
s、其他参数类型等。 另外,一个重要的注释
.pyi
文件应该与您正在注释的模块具有相同的名称,因此在本例中它应该是
inspect.pyi

现在,这只需打印出所有具有名为
object
的参数以及我们提供的“注释”(
object
)的函数:

def findsource(object:'object'): ...
def formatannotationrelativeto(object:'object'): ...
def getabsfile(object:'object'): ...
def getcomments(object:'object'): ...
def getdoc(object:'object'): ...
def getfile(object:'object'): ...
def getmembers(object:'object'): ...
def getmodule(object:'object'): ...
def getsource(object:'object'): ...
# .. and so on..

大多数生产就绪检查器将读取此
.pyi
文件并提供您需要的功能。

如果我的理解正确,这听起来像是存根文件的用例,如中所述:

存根文件是包含类型提示的文件,只供类型检查器使用,不在运行时使用

存根文件基本上满足了将代码与类型注释分离的要求,从而避免了复杂类型提示的膨胀和混淆效果。它们的前缀为
.pyi
,如果由
IDE
实现的类型检查器想要符合
PEP 484
,则必须始终由类型检查器检查(如果存在)

它们基本上由带注释的函数签名组成,其主体包含一个省略号


一种方法是使用helper函数写出
.pyi
,或者至少写出大部分内容。可能有很多方法可以做到这一点,而哪种方法最好可能是另一个问题

作为一个这样做的示例,我将写出一种方法来注释
inspect
模块中的每个函数,该模块的参数名为
object
,并且不以下划线开头。我正在输入这个特定的模块,因为我还将使用它来识别函数并获取它们的签名

inspect
模块中,我将使用、和函数

# gets members of inspect module {member_name: member_type} dict.
members = getmembers(inspect)  

# loop through members
for name, type in members:

    # grab functions that don't start with an underscore  
    if isfunction(type) and not name.startswith('_'):

        # grab its signature and
        # check if it has a parameter named object
        sig = signature(type)  
        if 'object' in sig.parameters:

            # add the annotation to the object parameter
            param = sig.parameter['object']
            s = sig.replace(parameters = [param.replace(annotation="object")])

            # here you normally write to .pyi file
            print('def {0} {1}: ...'.format(name, s))  
该逻辑可以扩展到
方法
s、其他参数类型等。 另外,一个重要的注释
.pyi
文件应该与您正在注释的模块具有相同的名称,因此在本例中它应该是
inspect.pyi

现在,这只需打印出所有具有名为
object
的参数以及我们提供的“注释”(
object
)的函数:

def findsource(object:'object'): ...
def formatannotationrelativeto(object:'object'): ...
def getabsfile(object:'object'): ...
def getcomments(object:'object'): ...
def getdoc(object:'object'): ...
def getfile(object:'object'): ...
def getmembers(object:'object'): ...
def getmodule(object:'object'): ...
def getsource(object:'object'): ...
# .. and so on..

大多数生产就绪的检查程序都会阅读此
.pyi
文件,并提供您需要的功能。

我想我的问题太模糊了。我添加了以下内容:我希望注释在IDE中具有更好的自动完成功能。也许(稍后)自动测试中的类型测试。我想我的问题太模糊了。我添加了以下内容:我希望注释在IDE中具有更好的自动完成功能。也许(稍后)自动测试中的类型测试。非常感谢您提供的详细答案。你得到赏金了!非常感谢您的详细回答。你得到赏金了!