简体   繁体   English

1作为函数声明中的参数类型

[英]1 as parameter type in function declaration

If you need to specify parameter type in Python, array in my example, you need to write something like this: 如果你需要在Python中指定参数类型,在我的例子中,你需要写这样的东西:

def my_function(param: list):
    pass

In Swift you specify parameter type like this: 在Swift中,您可以指定参数类型,如下所示:

func myFunction(param: [Any]) {
//
}

One day I made Swift-style mistake and wrote: 有一天,我犯了Swift风格的错误并写道:

def my_function_2(param: []):
    pass

Now I noticed it and try something more strange: 现在我注意到它并尝试更奇怪的事情:

def my_function_3(param: 1):
    pass

All this functions are valid and can be called in Python 3.6. 所有这些函数都是有效的,可以在Python 3.6中调用。 Function with expected parameter type one ... Why it happens, why I don't see any warnings and what kind of variable I would have to pass to functions 2 and 3 to satisfy parameter type I erroneously requested? 具有预期参数类型1的函数...为什么会发生这种情况,为什么我没有看到任何警告以及我必须传递给函数2和3以满足错误请求的参数类型I的变量类型?

Annotations have no meaning to Python's compiler and interpreter. 注释对Python的编译器和解释器没有意义。 1 As long as what you type is a syntactically valid expression, Python will evaluate it, store its value as part of the function's annotations, and leave it there for you to do whatever you want with (which is usually nothing). 1只要你键入的是一个语法上有效的表达式,Python就会对它进行评估,将其值存储为函数注释的一部分,然后将它留在那里为你做任何你想做的事情(通常都没有)。

In fact, you can see this being stored without a problem: 实际上,您可以看到存储没有问题:

>>> print(my_function_3.__annotations__)
{'param': 1}

The main point of annotations is for using a static type checker, as explained in PEP 484 (and the accompanying PEP 483 and PEP 482 for background). 注释的要点是使用静态类型检查器,如PEP 484 (以及随附的PEP 483PEP 482背景)中所述。

Static type checking is optional in Python, and generally done with a dedicated tool like mypy , or with tools integrated into IDEs like PyCharm . 静态类型检查在Python中是可选的,通常使用像mypy这样的专用工具,或者使用集成到像PyCharm这样的IDE中的工具来完成。

If you run such a checker against your code, it will complain. 如果你对你的代码运行这样的检查器,它会抱怨。 For example: 例如:

$ mypy testscript.py
testscript.py:1: error: invalid type comment or annotation

This error means that it can't figure out what type 1 is supposed to be. 此错误意味着它无法确定应该是什么类型1 2 2


One last thing: 最后一件事:

what kind of variable I would have to pass to functions 2 and 3 to satisfy parameter type I erroneously requested 我必须传递给函数2和3以满足错误请求的参数类型I的变量类型

There's no type that would satisfy that. 没有哪种类型可以满足这一要求。 Python's runtime type rules are more flexible than its (optional) static type rules, but they're not that flexible. Python的运行时类型规则比它(可选)静态类型的规则更灵活,但他们没有那么灵活。 3 3


1. However, they do have a meaning to at least one thing in the stdlib, the dataclass decorator . 但是,它们对stdlib( dataclass装饰器)中的至少一个东西确实有意义。

2. Mypy continues on from here, but with no more errors, even if you abuse the parameter in the body or call the function improperly. 2. Mypy继续从这里继续,但没有更多错误,即使您滥用正文中的参数或不正确地调用该函数。 As far as I can tell, it skips checking the body, and treats the function as if it took any parameters and returned an Any . 据我所知,它跳过检查正文,并将该函数视为采用任何参数并返回Any Which is pretty reasonable—that way you just get this one error instead of hundreds of useless ones that probably wouldn't mean anything. 这是非常合理的 - 你只是得到这一个错误,而不是数百个无用的错误,可能不会有任何意义。

3. You can't even test for it— isinstance(obj, 1) will raise an exception because 1 is not an instance of type . 3.你甚至无法测试它 - isinstance(obj, 1)会引发异常, 因为1不是type的实例 But if you could, it could only return true if obj was created by calling 1 (or a subclass of 1 , of which there are none) as a metaclass, which is impossible, or if obj.__class__ were set to 1 (or a subclass), which is impossible, or if int had an instance or subclass hook which accepted obj , which it doesn't. 但是,如果你能,它只能如果返回true obj通过调用创建1 (或子类1 ,其中有没有)作为元类,这是不可能的,或者如果obj.__class__分别设置为1 (或子类),这是不可能的,或者如果int有一个接受obj的实例或子类钩子,它没有。 But—at least in CPython and PyPy—it won't even get that far. 但是 - 至少在CPython和PyPy中 - 它甚至都不会那么遥远。 Of course you could always go below Python, below the C API, and directly modify the ob_type field of the struct underneath obj to point at the 1 object, but if you do that, anything you try to do with obj will just segfault. 当然,你总是可以在Python下面,在C API下面,并直接修改obj下面的struct的ob_type字段指向1对象,但如果你这样做,你尝试用obj做的任何事情都只是段错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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