Thanks to chun and cocoatomo for their answers and reference articles in the Discord community, we have made great strides in solving and convincing. thank you very much. I would like to take this opportunity to thank you.
When I was reading this article, I found the code that I was interested in in the comments of the article.
x = f"{quit()}"
while True:
print("hello")
As the article comment contributor said, when I execute this code, hello
is not output and it ends.
I felt a little uncomfortable here, so I looked it up.
Regarding f-string, according to the Official Document,
A formatted string literal or f-string is a string literal prefixed with'f'or'F'. These strings can contain replacement fields, which are expressions separated by curly braces {}. Formatted string literals are evaluated as expressions at run time, whereas other string literals are always constant and do not change.
And that. In other words, if you put a function inside {}, it will replace its return value with a field.
Formats a string, whether the return value of the function is an int, a list, or a dict.
In the end, even NoneType becomes a string " None "
, and f-string is a fairly powerful white thing.
** What the quit () function that broke this powerful f-string returned **
This was my first question.
First, I thought that if I knew what kind of "type" quit () returned, I could see a clue, so I executed the following code.
>>> print(type(quit()))
C:\work>
Rainy day ** The python interpreter itself has ended **
As mentioned above, if the return value is NoneType, the string " None "
will be output when you put it in f-string, so I expected that the return value of quit () would not be NoneType. Instead of getting no results, the whole interpreter is dropped ...
Even if you can't get the type, you can see what you're doing by looking at the source of the actual quit () function. I thought, and took a peek at quit in the built in.
builtin.pyi
def quit(code: object = ...) -> NoReturn: ...
** There is no return in the first place, and the mysterious No Return claims that it is not an omission or mistake **
I took it for granted that the function had a return, so I was already exhausted and decided to ask a question in the Discord community.
I was able to get a reply from the community. I will quote.
sys.exit (), exit (), quit () feels like throwing a SystemExit exception Reference: https://docs.python.org/3/library/constants.html
In other words, quit (), sys.exit (), exit (), etc. are ** functions that always give exceptions **.
As for the SystemExit exception that you told me, even if you execute quit () or sys.exit () normally, the exception cannot be caught and no traceback appears. This is because SystemExit exceptions are not ** Exceptions, but are directly inheriting BaseException, the main class they inherit. It seems that the exceptions that can be caught normally, KeyError and TypeError, are inherited from the Exception class, and SystemExit is not in it.
** BaseException is the masterpiece of all python exceptions **, and there are only four exception classes that directly inherit from it: SystemExit, GeneratorExit, KeyboardInterrupt, and Exception.
Keyboard Interrupt is a Ctrl + C
thing.
Exception is the base class for all other exceptions, and user-defined exceptions should also be based on it. When you write a code with a mistake, what is caught and output by Traceback is the one that inherits this Exception class, and the exception that directly inherits BaseException is not caught.
Use the traceback module to catch a BaseException. Let's catch the SystemExit exception that we expect to occur on the first line of the opening code.
import traceback
try:
x = f"{quit()}"
print(x)
except BaseException: #BaseException is specified just in case, but just except:But they will pick it up
print(traceback.format_exc())
The result is as follows
python
Traceback (most recent call last):
File "c:/work/catchBaseException.py", line 3, in <module>
x = f"{quit()}"
File "C:\Python\Python37\lib\_sitebuiltins.py", line 26, in __call__
raise SystemExit(code)
SystemExit: None
** I was able to catch the System Exit of BaseException safely **
This isn't that difficult, it's a type hint, a representation of the expected result.
Originally, it seems that the function implicitly return None
when return is not specified.
For example, the following code
python
def no_return():
pass
x = no_return()
print(type(x))
<class 'NoneType'>
Far from return None
, return itself is not set in the function no_return (), but the return type is NoneType.
In other words, the no_return function implicitly return None
.
However, this is the case when the function is executed normally to the end and there is no return.
** quit () and sys.exit () that end up throwing an exception don't even implicitly return None **
The type hint of a function describes the expected value of what type the function will return, but the expected result of these functions that even None does not return is that the content of the type hint is NoReturn
. It seems to be this way.
--quit (), sys.exit () raise exception SystemExit
--SystemExit is a special one that directly inherits the main exception class BaseException.
--A function that does not specify return implicitly return None
, but it is not even done by the exception SystemExit, and the execution result does not even return None.
--For functions that do not return None, write NoReturn in the type hint.
Official documentation https://docs.python.org/ja/3/library/constants.html https://docs.python.org/ja/3/library/exceptions.html#SystemExit https://docs.python.org/ja/3/library/typing.html#typing.NoReturn Qiita https://qiita.com/ksato9700/items/44caf7bf0329fb987499 https://qiita.com/hayata-yamamoto/items/259238dad038b5bee51c Pythonjp Official Discord https://www.python.jp/pages/pythonjp_discord.html
Recommended Posts