What's the difference between these two functions? I've seen people put quotes around type annotations and other times leave them out but I couldn't find why people choose to use one or the other.
def do_something(entity: Entity):
pass
def do_something(entity: 'Entity'):
pass
Are there advantages or disadvantages to any of these?
Quotes are special characters in Python used to represent string data type. If a single or double quote needs to be part of a string, we can do that in a couple of ways. Let us explore that…
There are many more exciting things you can do with type annotations, especially since they are now a core part of the Python language. For instance, Python 3.7 has introduced data classes, an exciting new way of generating classes for simple yet efficient data storage.
Triple quotes for multiline strings can also be used to include both single and double quotes in the same string. Here is an example… If the input string is generated or processed in the code and you want to append the quotes. You can use Python formatting in addition to the methods we just mentioned.
Type annotations — also known as type signatures — are used to indicate the datatypes of variables and input/outputs of functions and methods. In many languages, datatypes are explicitly stated. In these languages, if you don’t declare your datatype — the code will not run. char hello[] = "hello world!";
Putting quotes around type hints is something that makes sense when making a Forward Reference according to PEP 484. In this case putting quotes around a name is used to subdue a NameError that would occur.
In other cases, don't use quotes, it doesn't result in the hint you want:
>>> def bad_foo(a: 'int'):
... pass
>>> def good_foo(a: int):
... pass
>>> bad_foo.__annotations__['a'] == good_foo.__annotations__['a']
False
though for now type checkers (mypy, atleast) don't seem to treat these differently, I wouldn't be sure if that would be the case in the future. Best to be clear and not use quotes when you actually don't need them.
Apparently it can also cause runtime exceptions if you don't quote them in some situations. See this comment. I have no idea why, but it definitely does:
~ python3
Python 3.9.2 (default, Mar 26 2021, 23:27:12)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def main() -> OrderedDict[str, str]:
... x: OrderedDict[str, str] = OrderedDict()
... print(x)
... return x
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
>>> def main() -> 'OrderedDict[str, str]':
... x: OrderedDict[str, str] = OrderedDict()
... print(x)
... return x
...
>>>
However you can avoid it by using from __future__ import annotations
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With