diff --git a/README.en.md b/README.en.md new file mode 100644 index 00000000..2a39aa0b --- /dev/null +++ b/README.en.md @@ -0,0 +1,220 @@ +# Playground and Cheatsheet for Learning Python + +[](https://travis-ci.org/trekhleb/learn-python) + +> This is a collection of Python scripts that are split by [topics](#table-of-contents) and contain +code examples with explanations, different use cases and links to further readings. + +_Read this in_ [_Português_](README.pt-BR.md). + +It is a **playground** because you may change or add the code to see how it works +and [test it out](#testing-the-code) using assertions. It also allows you +to [lint the code](#linting-the-code) you've wrote and check if it fits to Python code style guide. +Altogether it might make your learning process to be more interactive and it might help you to keep +code quality pretty high from very beginning. + +It is a **cheatsheet** because you may get back to these code examples once you want to recap the +syntax of [standard Python statements and constructions](#table-of-contents). Also because the +code is full of assertions you'll be able to see expected functions/statements output right away +without launching them. + +> _You might also be interested in 🤖 [Interactive Machine Learning Experiments](https://github.com/trekhleb/machine-learning-experiments)_ + +## How to Use This Repository + +Each Python script in this repository has the following structure: + +```python +"""Lists <--- Name of the topic here + +# @see: https://www.learnpython.org/en/Lists <-- Link to further readings goes here + +Here might go more detailed explanation of the current topic (i.e. general info about Lists). +""" + + +def test_list_type(): + """Explanation of sub-topic goes here. + + Each file contains test functions that illustrate sub-topics (i.e. lists type, lists methods). + """ + + # Here is an example of how to build a list. <-- Comments here explain the action + squares = [1, 4, 9, 16, 25] + + # Lists can be indexed and sliced. + # Indexing returns the item. + assert squares[0] == 1 # <-- Assertions here illustrate the result. + # Slicing returns a new list. + assert squares[-3:] == [9, 16, 25] # <-- Assertions here illustrate the result. +``` + +So normally you might want to do the following: + +- [Find the topic](#table-of-contents) you want to learn or recap. +- Read comments and/or documentation that is linked in each script's docstring (as in example above). +- Look at code examples and assertions to see usage examples and expected output. +- Change code or add new assertions to see how things work. +- [Run tests](#testing-the-code) and [lint the code](#linting-the-code) to see if it work and is +written correctly. + +## Table of Contents + +1. **Getting Started** + - [What is Python](src/getting_started/what_is_python.md) + - [Python Syntax](src/getting_started/python_syntax.md) + - [Variables](src/getting_started/test_variables.py) +2. **Operators** + - [Arithmetic Operators](src/operators/test_arithmetic.py) (`+`, `-`, `*`, `/`, `//`, `%`, `**`) + - [Bitwise Operators](src/operators/test_bitwise.py) (`&`, `|`, `^`, `>>`, `<<`, `~`) + - [Assignment Operators](src/operators/test_assigment.py) (`=`, `+=`, `-=`, `/=`, `//=` etc.) + - [Comparison Operator](src/operators/test_comparison.py) (`==`, `!=`, `>`, `<`, `>=`, `<=`) + - [Logical Operators](src/operators/test_logical.py) (`and`, `or`, `not`) + - [Identity Operators](src/operators/test_identity.py) (`is`, `is not`) + - [Membership Operators](src/operators/test_membership.py) (`in`, `not in`) +3. **Data Types** + - [Numbers](src/data_types/test_numbers.py) (including booleans) + - [Strings](src/data_types/test_strings.py) and their methods + - [Lists](src/data_types/test_lists.py) and their methods (including list comprehensions) + - [Tuples](src/data_types/test_tuples.py) + - [Sets](src/data_types/test_sets.py) and their methods + - [Dictionaries](src/data_types/test_dictionaries.py) + - [Type Casting](src/data_types/test_type_casting.py) +4. **Control Flow** + - [The `if` statement](src/control_flow/test_if.py) + - [The `for` statement](src/control_flow/test_for.py) (and `range()` function) + - [The `while` statement](src/control_flow/test_while.py) + - [The `try` statements](src/control_flow/test_try.py) + - [The `break` statement](src/control_flow/test_break.py) + - [The `continue` statement](src/control_flow/test_continue.py) +5. **Functions** + - [Function Definition](src/functions/test_function_definition.py) (`def` and `return` statements) + - [Scopes of Variables Inside Functions](src/functions/test_function_scopes.py) (`global` and `nonlocal` statements) + - [Default Argument Values](src/functions/test_function_default_arguments.py) + - [Keyword Arguments](src/functions/test_function_keyword_arguments.py) + - [Arbitrary Argument Lists](src/functions/test_function_arbitrary_arguments.py) + - [Unpacking Argument Lists](src/functions/test_function_unpacking_arguments.py) (`*` and `**` statements) + - [Lambda Expressions](src/functions/test_lambda_expressions.py) (`lambda` statement) + - [Documentation Strings](src/functions/test_function_documentation_string.py) + - [Function Annotations](src/functions/test_function_annotations.py) + - [Function Decorators](src/functions/test_function_decorators.py) +6. **Classes** + - [Class Definition](src/classes/test_class_definition.py) (`class` statement) + - [Class Objects](src/classes/test_class_objects.py) + - [Instance Objects](src/classes/test_instance_objects.py) + - [Method Objects](src/classes/test_method_objects.py) + - [Class and Instance Variables](src/classes/test_class_and_instance_variables.py) + - [Inheritance](src/classes/test_inheritance.py) + - [Multiple Inheritance](src/classes/test_multiple_inheritance.py) +7. **Modules** + - [Modules](src/modules/test_modules.py) (`import` statement) + - [Packages](src/modules/test_packages.py) +8. **Errors and Exceptions** + - [Handling Exceptions](src/exceptions/test_handle_exceptions.py) (`try` statement) + - [Raising Exceptions](src/exceptions/test_raise_exceptions.py) (`raise` statement) +9. **Files** + - [Reading and Writing](src/files/test_file_reading.py) (`with` statement) + - [Methods of File Objects](src/files/test_file_methods.py) +10. **Additions** + - [The `pass` statement](src/additions/test_pass.py) + - [Generators](src/additions/test_generators.py) (`yield` statement) +11. **Brief Tour of the Standard Libraries** + - [Serialization](src/standard_libraries/test_json.py) (`json` library) + - [File Wildcards](src/standard_libraries/test_glob.py) (`glob` library) + - [String Pattern Matching](src/standard_libraries/test_re.py) (`re` library) + - [Mathematics](src/standard_libraries/test_math.py) (`math`, `random`, `statistics` libraries) + - [Dates and Times](src/standard_libraries/test_datetime.py) (`datetime` library) + - [Data Compression](src/standard_libraries/test_zlib.py) (`zlib` library) + +## Prerequisites + +**Installing Python** + +Make sure that you have [Python3 installed](https://realpython.com/installing-python/) on your machine. + +You might want to use [venv](https://docs.python.org/3/library/venv.html) standard Python library +to create virtual environments and have Python, pip and all dependent packages to be installed and +served from the local project directory to avoid messing with system wide packages and their +versions. + +Depending on your installation you might have access to Python3 interpreter either by +running `python` or `python3`. The same goes for pip package manager - it may be accessible either +by running `pip` or `pip3`. + +You may check your Python version by running: + +```bash +python --version +``` + +Note that in this repository whenever you see `python` it will be assumed that it is Python **3**. + +**Installing dependencies** + +Install all dependencies that are required for the project by running: + +```bash +pip install -r requirements.txt +``` + +## Testing the Code + +Tests are made using [pytest](https://docs.pytest.org/en/latest/) framework. + +You may add new tests for yourself by adding files and functions with `test_` prefix +(i.e. `test_topic.py` with `def test_sub_topic()` function inside). + +To run all the tests please execute the following command from the project root folder: + +```bash +pytest +``` + +To run specific tests please execute: + +```bash +pytest ./path/to/the/test_file.py +``` + +## Linting the Code + +Linting is done using [pylint](http://pylint.pycqa.org/) and [flake8](http://flake8.pycqa.org/en/latest/) libraries. + +### PyLint + +To check if the code is written with respect +to [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide please run: + +```bash +pylint ./src/ +``` + +In case if linter will detect error (i.e. `missing-docstring`) you may want to read more about +specific error by running: + +```bash +pylint --help-msg=missing-docstring +``` + +[More about PyLint](http://pylint.pycqa.org/) + +### Flake8 + +To check if the code is written with respect +to [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide please run: + +```bash +flake8 ./src +``` + +Or if you want to have more detailed output you may run: + +```bash +flake8 ./src --statistics --show-source --count +``` + +[More about Flake8](http://flake8.pycqa.org/en/latest/) + +## Supporting the project + +You may support this project via ❤️️ [GitHub](https://github.com/sponsors/trekhleb) or ❤️️ [Patreon](https://www.patreon.com/trekhleb). diff --git a/README.md b/README.md index 2a39aa0b..015b9b9b 100644 --- a/README.md +++ b/README.md @@ -1,145 +1,135 @@ -# Playground and Cheatsheet for Learning Python +# Python 学习笔记 [](https://travis-ci.org/trekhleb/learn-python) -> This is a collection of Python scripts that are split by [topics](#table-of-contents) and contain -code examples with explanations, different use cases and links to further readings. +> 这是 Python 脚本的集合,按 [目录](#目录)划分,包含带有解释的代码示例、不同的用例和进一步阅读的链接。 -_Read this in_ [_Português_](README.pt-BR.md). -It is a **playground** because you may change or add the code to see how it works -and [test it out](#testing-the-code) using assertions. It also allows you -to [lint the code](#linting-the-code) you've wrote and check if it fits to Python code style guide. -Altogether it might make your learning process to be more interactive and it might help you to keep -code quality pretty high from very beginning. +这是一个**练习场**,因为您可以更改或添加代码以查看它是如何工作的, +并使用断言 [测试代码](#测试代码)。它还允许您 [代码检测](#代码检测) +并检查它是否符合 Python 代码风格指南。 +总而言之,它可能会使您的学习过程更具交互性,并且可能会帮助您从一开始就保持较高的代码质量。 -It is a **cheatsheet** because you may get back to these code examples once you want to recap the -syntax of [standard Python statements and constructions](#table-of-contents). Also because the -code is full of assertions you'll be able to see expected functions/statements output right away -without launching them. +这是一个**备忘单**,因为一旦您想回顾[标准 Python 语句和结构](#目录)的语法,您可能会回到这些代码示例。 +此外,由于代码中充满了断言,您无需启动它们就可以立即看到预期的函数语句输出。 -> _You might also be interested in 🤖 [Interactive Machine Learning Experiments](https://github.com/trekhleb/machine-learning-experiments)_ +> _你可能也对🤖感兴趣 [交互式机器学习实验](https://github.com/trekhleb/machine-learning-experiments)_ -## How to Use This Repository +## 如何使用此存储库 -Each Python script in this repository has the following structure: +此存储库中的每个 Python 脚本都具有以下结构: ```python -"""Lists <--- Name of the topic here +"""Lists <--- 这里的主题名称 -# @see: https://www.learnpython.org/en/Lists <-- Link to further readings goes here +# @see: https://www.learnpython.org/en/Lists <-- 进一步阅读的链接在这里 -Here might go more detailed explanation of the current topic (i.e. general info about Lists). +这里可能会对当前主题进行更详细的解释(即关于列表的一般信息)。 """ def test_list_type(): - """Explanation of sub-topic goes here. - - Each file contains test functions that illustrate sub-topics (i.e. lists type, lists methods). + """ + 子主题的解释在这里。每个文件都包含说明子主题的测试函数(即列表类型、列表方法)。 """ - # Here is an example of how to build a list. <-- Comments here explain the action + # 以下是如何构建列表的示例。 <-- 这里的评论解释了这个动作 squares = [1, 4, 9, 16, 25] - # Lists can be indexed and sliced. - # Indexing returns the item. - assert squares[0] == 1 # <-- Assertions here illustrate the result. - # Slicing returns a new list. - assert squares[-3:] == [9, 16, 25] # <-- Assertions here illustrate the result. + # 列表可以被索引和切片。 + # 索引返回项目。 + assert squares[0] == 1 # <-- 这里的断言说明了结果。 + # 切片返回一个新列表。 + assert squares[-3:] == [9, 16, 25] # <-- 这里的断言说明了结果。 ``` -So normally you might want to do the following: - -- [Find the topic](#table-of-contents) you want to learn or recap. -- Read comments and/or documentation that is linked in each script's docstring (as in example above). -- Look at code examples and assertions to see usage examples and expected output. -- Change code or add new assertions to see how things work. -- [Run tests](#testing-the-code) and [lint the code](#linting-the-code) to see if it work and is -written correctly. - -## Table of Contents - -1. **Getting Started** - - [What is Python](src/getting_started/what_is_python.md) - - [Python Syntax](src/getting_started/python_syntax.md) - - [Variables](src/getting_started/test_variables.py) -2. **Operators** - - [Arithmetic Operators](src/operators/test_arithmetic.py) (`+`, `-`, `*`, `/`, `//`, `%`, `**`) - - [Bitwise Operators](src/operators/test_bitwise.py) (`&`, `|`, `^`, `>>`, `<<`, `~`) - - [Assignment Operators](src/operators/test_assigment.py) (`=`, `+=`, `-=`, `/=`, `//=` etc.) - - [Comparison Operator](src/operators/test_comparison.py) (`==`, `!=`, `>`, `<`, `>=`, `<=`) - - [Logical Operators](src/operators/test_logical.py) (`and`, `or`, `not`) - - [Identity Operators](src/operators/test_identity.py) (`is`, `is not`) - - [Membership Operators](src/operators/test_membership.py) (`in`, `not in`) -3. **Data Types** - - [Numbers](src/data_types/test_numbers.py) (including booleans) - - [Strings](src/data_types/test_strings.py) and their methods - - [Lists](src/data_types/test_lists.py) and their methods (including list comprehensions) - - [Tuples](src/data_types/test_tuples.py) - - [Sets](src/data_types/test_sets.py) and their methods - - [Dictionaries](src/data_types/test_dictionaries.py) - - [Type Casting](src/data_types/test_type_casting.py) -4. **Control Flow** - - [The `if` statement](src/control_flow/test_if.py) - - [The `for` statement](src/control_flow/test_for.py) (and `range()` function) - - [The `while` statement](src/control_flow/test_while.py) - - [The `try` statements](src/control_flow/test_try.py) - - [The `break` statement](src/control_flow/test_break.py) - - [The `continue` statement](src/control_flow/test_continue.py) -5. **Functions** - - [Function Definition](src/functions/test_function_definition.py) (`def` and `return` statements) - - [Scopes of Variables Inside Functions](src/functions/test_function_scopes.py) (`global` and `nonlocal` statements) - - [Default Argument Values](src/functions/test_function_default_arguments.py) - - [Keyword Arguments](src/functions/test_function_keyword_arguments.py) - - [Arbitrary Argument Lists](src/functions/test_function_arbitrary_arguments.py) - - [Unpacking Argument Lists](src/functions/test_function_unpacking_arguments.py) (`*` and `**` statements) - - [Lambda Expressions](src/functions/test_lambda_expressions.py) (`lambda` statement) - - [Documentation Strings](src/functions/test_function_documentation_string.py) - - [Function Annotations](src/functions/test_function_annotations.py) - - [Function Decorators](src/functions/test_function_decorators.py) -6. **Classes** - - [Class Definition](src/classes/test_class_definition.py) (`class` statement) - - [Class Objects](src/classes/test_class_objects.py) - - [Instance Objects](src/classes/test_instance_objects.py) - - [Method Objects](src/classes/test_method_objects.py) - - [Class and Instance Variables](src/classes/test_class_and_instance_variables.py) - - [Inheritance](src/classes/test_inheritance.py) - - [Multiple Inheritance](src/classes/test_multiple_inheritance.py) -7. **Modules** - - [Modules](src/modules/test_modules.py) (`import` statement) - - [Packages](src/modules/test_packages.py) -8. **Errors and Exceptions** - - [Handling Exceptions](src/exceptions/test_handle_exceptions.py) (`try` statement) - - [Raising Exceptions](src/exceptions/test_raise_exceptions.py) (`raise` statement) -9. **Files** - - [Reading and Writing](src/files/test_file_reading.py) (`with` statement) - - [Methods of File Objects](src/files/test_file_methods.py) -10. **Additions** - - [The `pass` statement](src/additions/test_pass.py) - - [Generators](src/additions/test_generators.py) (`yield` statement) -11. **Brief Tour of the Standard Libraries** - - [Serialization](src/standard_libraries/test_json.py) (`json` library) - - [File Wildcards](src/standard_libraries/test_glob.py) (`glob` library) - - [String Pattern Matching](src/standard_libraries/test_re.py) (`re` library) - - [Mathematics](src/standard_libraries/test_math.py) (`math`, `random`, `statistics` libraries) - - [Dates and Times](src/standard_libraries/test_datetime.py) (`datetime` library) - - [Data Compression](src/standard_libraries/test_zlib.py) (`zlib` library) - -## Prerequisites - -**Installing Python** - -Make sure that you have [Python3 installed](https://realpython.com/installing-python/) on your machine. - -You might want to use [venv](https://docs.python.org/3/library/venv.html) standard Python library -to create virtual environments and have Python, pip and all dependent packages to be installed and -served from the local project directory to avoid messing with system wide packages and their -versions. - -Depending on your installation you might have access to Python3 interpreter either by -running `python` or `python3`. The same goes for pip package manager - it may be accessible either -by running `pip` or `pip3`. +所以通常你可能想要执行以下操作: + +- [Find the topic](#table-of-contents)你想学习或回顾。 +- 阅读每个脚本的文档字符串中链接的注释和/或文档(如上例所示)。 +- 查看代码示例和断言以查看使用示例和预期输出。 +- 更改代码或添加新断言以查看工作方式。 +- [Run tests](#testing-the-code) and [lint the code](#linting-the-code) 看看它是否有效并且是否正确写入。 + +## 目录 + +1. **入门** + - [什么是 Python](src/getting_started/what_is_python.md) + - [Python 语法](src/getting_started/python_syntax.md) + - [变量](src/getting_started/test_variables.py) +2. **运算符** + - [算术运算符](src/operators/test_arithmetic.py) (`+`, `-`, `*`, `/`, `//`, `%`, `**`) + - [位运算符](src/operators/test_bitwise.py) (`&`, `|`, `^`, `>>`, `<<`, `~`) + - [赋值运算符](src/operators/test_assigment.py) (`=`, `+=`, `-=`, `/=`, `//=` etc.) + - [比较运算符](src/operators/test_comparison.py) (`==`, `!=`, `>`, `<`, `>=`, `<=`) + - [逻辑运算符](src/operators/test_logical.py) (`and`, `or`, `not`) + - [恒等运算符](src/operators/test_identity.py) (`is`, `is not`) + - [成员运算符](src/operators/test_membership.py) (`in`, `not in`) +3. **数据类型** + - [数字](src/data_types/test_numbers.py) (其中包括布尔值) + - [字符串](src/data_types/test_strings.py) 以及方法 + - [列表](src/data_types/test_lists.py) 以及方法(包括列表推导式) + - [元组](src/data_types/test_tuples.py) + - [集合](src/data_types/test_sets.py)及其方法 + - [字典](src/data_types/test_dictionaries.py) + - [类型转换](src/data_types/test_type_casting.py) +4. **控制** + - [if](src/control_flow/test_if.py) + - [for](src/control_flow/test_for.py) (以及 `range()` 函数) + - [while](src/control_flow/test_while.py) + - [try](src/control_flow/test_try.py) + - [break](src/control_flow/test_break.py) + - [continue](src/control_flow/test_continue.py) +5. **函数** + - [函数定义](src/functions/test_function_definition.py) (`def` and `return` statements) + - [函数内部变量的作用域](src/functions/test_function_scopes.py) (`global` and `nonlocal` statements) + - [默认参数值](src/functions/test_function_default_arguments.py) + - [关键字参数](src/functions/test_function_keyword_arguments.py) + - [任意的参数列表](src/functions/test_function_arbitrary_arguments.py) + - [拆包参数列表](src/functions/test_function_unpacking_arguments.py) (`*` and `**` statements) + - [Lambda表达式](src/functions/test_lambda_expressions.py) (`lambda` statement) + - [文档字符串](src/functions/test_function_documentation_string.py) + - [函数注释](src/functions/test_function_annotations.py) + - [函数修饰符](src/functions/test_function_decorators.py) +6. **类** + - [类定义](src/classes/test_class_definition.py) (`class` statement) + - [类对象](src/classes/test_class_objects.py) + - [实例对象](src/classes/test_instance_objects.py) + - [方法对象](src/classes/test_method_objects.py) + - [类和实例变量](src/classes/test_class_and_instance_variables.py) + - [继承](src/classes/test_inheritance.py) + - [多重继承](src/classes/test_multiple_inheritance.py) +7. **组件** + - [模块](src/modules/test_modules.py) (`import` statement) + - [包](src/modules/test_packages.py) +8. **错误和异常** + - [处理异常](src/exceptions/test_handle_exceptions.py) (`try` statement) + - [提高异常](src/exceptions/test_raise_exceptions.py) (`raise` statement) +9. **文件** + - [读与写](src/files/test_file_reading.py) (`with` statement) + - [文件对象的方法](src/files/test_file_methods.py) +10. **附加物** + - [`pass` 声明](src/additions/test_pass.py) + - [生成器](src/additions/test_generators.py) (`yield` 声明) +11. **标准库简介** + - [序列化](src/standard_libraries/test_json.py) (`json` library) + - [文件通配符](src/standard_libraries/test_glob.py) (`glob` library) + - [字符串匹配](src/standard_libraries/test_re.py) (`re` library) + - [数学运算](src/standard_libraries/test_math.py) (`math`, `random`, `statistics` libraries) + - [日期和时间](src/standard_libraries/test_datetime.py) (`datetime` library) + - [数据压缩](src/standard_libraries/test_zlib.py) (`zlib` library) + +## 预备知识 + +**安装Python** + +确保你安装了[Python3](https://realpython.com/installing-python/) on your machine. + +你可能想要使用[venv](https://docs.python.org/3/library/venv.html)标准Python库 +创建虚拟环境并安装Python、pip和所有依赖包从本地项目目录提供,以避免与系统范围的包及其版本。 + +根据你的安装,你可以通过运行`python` 或 `python3`。pip包管理器也是如此——它也可能是可访问的 +通过运行 `pip `或` pip3 `。 You may check your Python version by running: @@ -157,40 +147,39 @@ Install all dependencies that are required for the project by running: pip install -r requirements.txt ``` -## Testing the Code +## 测试代码 -Tests are made using [pytest](https://docs.pytest.org/en/latest/) framework. +测试使用 [pytest](https://docs.pytest.org/en/latest/) 框架. -You may add new tests for yourself by adding files and functions with `test_` prefix -(i.e. `test_topic.py` with `def test_sub_topic()` function inside). +您可以通过 `test_` 作为前缀添加文件和函数为自己添加新的测试 +(例如: 在 `test_topic.py` 里添加 `def test_sub_topic()` 函数). -To run all the tests please execute the following command from the project root folder: +要运行所有测试,请从项目根文件夹执行以下命令: ```bash pytest ``` -To run specific tests please execute: +要运行特定的测试,请执行: ```bash pytest ./path/to/the/test_file.py ``` -## Linting the Code +## 代码检测 -Linting is done using [pylint](http://pylint.pycqa.org/) and [flake8](http://flake8.pycqa.org/en/latest/) libraries. +代码检测用的是 [pylint](http://pylint.pycqa.org/) 和 [flake8](http://flake8.pycqa.org/en/latest/) 库. ### PyLint -To check if the code is written with respect -to [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide please run: +来检查代码是否按 [PEP 8](https://www.python.org/dev/peps/pep-0008/) 规定编写,请执行: ```bash pylint ./src/ ``` -In case if linter will detect error (i.e. `missing-docstring`) you may want to read more about -specific error by running: +以防linter检测到错误 (i.e. `missing-docstring`) 你可能想读更多关于 +具体运行错误: ```bash pylint --help-msg=missing-docstring @@ -200,21 +189,14 @@ pylint --help-msg=missing-docstring ### Flake8 -To check if the code is written with respect -to [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide please run: +来检查代码是否按 [PEP 8](https://www.python.org/dev/peps/pep-0008/) 规定编写,请执行: ```bash flake8 ./src ``` -Or if you want to have more detailed output you may run: +或者,如果你想有更详细的输出,你可以运行: ```bash flake8 ./src --statistics --show-source --count ``` - -[More about Flake8](http://flake8.pycqa.org/en/latest/) - -## Supporting the project - -You may support this project via ❤️️ [GitHub](https://github.com/sponsors/trekhleb) or ❤️️ [Patreon](https://www.patreon.com/trekhleb). diff --git a/README.pt-BR.md b/README.pt-BR.md index e6bd025f..9008a1ff 100644 --- a/README.pt-BR.md +++ b/README.pt-BR.md @@ -5,7 +5,7 @@ > Essa é uma coleção de scripts Python dividida em [tópicos](#índice) que contém exemplos de código com explicações, diferentes usos e links para outras leituras. -_Ler em_ [_English_](README.md). +_Ler em_ [_English_](README.en.md). É um **playground** porque você pode fazer alterações no código para ver como ele se comporta, além de [testá-lo](#testando-o-código) usando asserções. Também é possível diff --git a/src/additions/test_generators.py b/src/additions/test_generators.py index ff3bce26..3b563fde 100644 --- a/src/additions/test_generators.py +++ b/src/additions/test_generators.py @@ -2,31 +2,28 @@ @see: https://www.learnpython.org/en/Generators -Generators are used to create iterators, but with a different approach. Generators are simple -functions which return an iterable set of items, one at a time, in a special way. +生成器用于创建迭代器,但采用了不同的方法。生成器是一个简单的函数,它以一种特殊的方式每次返回一个可迭代的项集。 -When an iteration over a set of item starts using the for statement, the generator is run. Once the -generator's function code reaches a "yield" statement, the generator yields its execution back to -the for loop, returning a new value from the set. The generator function can generate as many -values (possibly infinite) as it wants, yielding each one in its turn. +当使用for语句开始对一组项进行迭代时,将运行生成器。 +一旦生成器的函数代码到达“yield”语句, 生成器将其执行返回给for循环,并从集合返回一个新值。 +生成器函数可以生成任意多的值(可能是无限),并依次生成每个值。 """ import random def lottery(): - """Generator function example. + """生成器函数的例子。 - Here is a simple example of a generator function which returns random integers. - This function decides how to generate the random numbers on its own, and executes the yield - statements one at a time, pausing in between to yield execution back to the main for loop. + 下面是一个返回随机整数的生成器函数的简单示例。 + 这个函数决定如何自己生成随机数, 一次一个地执行yield语句, 在两个循环之间暂停,使执行返回主for循环。 """ - # returns first 3 random numbers between 1 and 10 + # 返回1到10之间的前3个随机数字 # pylint: disable=unused-variable for i in range(3): yield random.randint(1, 10) - # returns a 4th number between 10 and 20 + # 返回10到20之间的第4个数字 yield random.randint(10, 20) diff --git a/src/additions/test_pass.py b/src/additions/test_pass.py index 57a6de9b..81c50dad 100644 --- a/src/additions/test_pass.py +++ b/src/additions/test_pass.py @@ -1,46 +1,42 @@ -"""PASS statement +"""pass 语句 @see: https://docs.python.org/3/tutorial/controlflow.html -The pass statement does nothing. It can be used when a statement is required syntactically but -the program requires no action. +pass 语句什么也不做。当语法上需要一个语句,但程序不需要任何操作时,可以使用它。 """ def test_pass_in_function(): - """PASS statement in function + """函数中的PASS语句 - "Pass" can be used as a place-holder for a function or conditional body when you are working on - new code, allowing you to keep thinking at a more abstract level. + 当您处理新代码时,“Pass”可以用作函数或条件体的占位符,使您能够在更抽象的层次上思考。 - The pass statement below is silently ignored but it makes current test_pass() function valid. + 下面的pass语句被静默地忽略,但是它使当前的test_pass()函数有效。 """ pass def test_pass_in_loop(): - """PASS in loops. + """pass 循环。 - "Pass" can be used when a statement is required syntactically but the program requires no - action. For example: + “Pass”可以在语法上需要一个语句但程序不需要任何操作时使用。例如: """ # pylint: disable=unused-variable for number in range(100): - # It just don't do anything but for loop is still valid. + # 它什么都不做,但是for循环仍然有效。 pass - # Example above is quite useless but it was given just for illustration of the idea. - # The more useful example might be: + # 上面的例子是完全没用的,但它只是为了说明这个想法。更有用的例子可能是: # # while True: - # pass # Busy-wait for keyboard interrupt (Ctrl+C) + # pass # 忙碌等待键盘中断(Ctrl+C) # pylint: disable=too-few-public-methods class MyEmptyClass: - """PASS statement in class + """类的PASS语句 - "Pass" is commonly used for creating minimal classes like current one. + “传递”通常用于创建最小类,如当前类。 """ pass diff --git a/src/classes/test_class_and_instance_variables.py b/src/classes/test_class_and_instance_variables.py index c4004d79..e037b245 100644 --- a/src/classes/test_class_and_instance_variables.py +++ b/src/classes/test_class_and_instance_variables.py @@ -1,52 +1,50 @@ -"""Class and Instance Variables. +"""类和实例变量。 @see: https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables -Generally speaking, instance variables are for data unique to each instance and class variables are -for attributes and methods shared by all instances of the class. +一般来说,实例变量用于每个实例唯一的数据,类变量用于类的所有实例共享的属性和方法。 """ def test_class_and_instance_variables(): - """Class and Instance Variables.""" + """类和实例变量。""" # pylint: disable=too-few-public-methods class Dog: """Dog class example""" - kind = 'canine' # Class variable shared by all instances. + kind = 'canine' # 所有实例共享的类变量. def __init__(self, name): - self.name = name # Instance variable unique to each instance. + self.name = name # 实例变量对每个实例是唯一的。 fido = Dog('Fido') buddy = Dog('Buddy') - # Shared by all dogs. + # 所有的狗都有。 assert fido.kind == 'canine' assert buddy.kind == 'canine' - # Unique to fido. + # fido 独有。 assert fido.name == 'Fido' - # Unique to buddy. + # buddy 独有。 assert buddy.name == 'Buddy' - # Shared data can have possibly surprising effects with involving mutable objects such as lists - # and dictionaries. For example, the tricks list in the following code should not be used as a - # class variable because just a single list would be shared by all Dog instances. + # 如果涉及到诸如列表和字典之类的可变对象,共享数据可能会产生令人惊讶的效果。 + # 例如,以下代码中的 tricks 列表不应该用作类变量,因为所有 Dog 实例只共享一个列表。 # pylint: disable=too-few-public-methods class DogWithSharedTricks: - """Dog class example with wrong shared variable usage""" - tricks = [] # Mistaken use of a class variable (see below) for mutable objects. + """共享变量使用错误的 Dog 类例子""" + tricks = [] # 错误地将类变量用于可变对象(见下文)。 def __init__(self, name): - self.name = name # Instance variable unique to each instance. + self.name = name # 实例变量对每个实例是唯一的。 def add_trick(self, trick): """Add trick to the dog - This function illustrate mistaken use of mutable class variable tricks (see below). + 这个函数说明了可变类变量的错误使用(见下文)。 """ self.tricks.append(trick) @@ -56,23 +54,21 @@ def add_trick(self, trick): fido.add_trick('roll over') buddy.add_trick('play dead') - assert fido.tricks == ['roll over', 'play dead'] # unexpectedly shared by all dogs - assert buddy.tricks == ['roll over', 'play dead'] # unexpectedly shared by all dogs + assert fido.tricks == ['roll over', 'play dead'] # 没想到所有的 Dog 都有 + assert buddy.tricks == ['roll over', 'play dead'] # 没想到所有的 Dog 都有 - # Correct design of the class should use an instance variable instead: + # 正确的类设计应该使用实例变量: # pylint: disable=too-few-public-methods class DogWithTricks: """Dog class example""" def __init__(self, name): - self.name = name # Instance variable unique to each instance. - self.tricks = [] # creates a new empty list for each dog + self.name = name # 实例变量对每个实例是唯一的。 + self.tricks = [] # 为每只狗创建一个新的空列表 def add_trick(self, trick): """Add trick to the dog - - This function illustrate mistaken use of mutable class variable tricks (see below). """ self.tricks.append(trick) diff --git a/src/classes/test_class_definition.py b/src/classes/test_class_definition.py index 9251c60e..3c81eee0 100644 --- a/src/classes/test_class_definition.py +++ b/src/classes/test_class_definition.py @@ -1,45 +1,40 @@ -"""Class Definition Syntax. +"""类定义的语法。 @see: https://docs.python.org/3/tutorial/classes.html -Python is an object oriented programming language. -Almost everything in Python is an object, with its properties and methods. -A Class is like an object constructor, or a "blueprint" for creating objects. +Python 是一种面向对象的编程语言。 +Python 中的几乎所有东西都是对象,包括它的属性和方法。 +类就像一个对象构造函数,或者创建对象的“蓝图”。 """ def test_class_definition(): - """Class definition.""" + """类定义""" - # Class definitions, like function definitions (def statements) must be executed before they - # have any effect. (You could conceivably place a class definition in a branch of an if - # statement, or inside a function.) + # 类定义,就像函数定义(def语句)一样,必须在它们生效之前执行。(可以将类定义放在if语句的分支中,或者函数中。) class GreetingClass: - """Example of the class definition + """类定义的示例 - This class contains two public methods and doesn't contain constructor. + 该类包含两个公共方法,不包含构造函数。 """ name = 'user' def say_hello(self): - """Class method.""" - # The self parameter is a reference to the class itself, and is used to access variables - # that belongs to the class. It does not have to be named self , you can call it - # whatever you like, but it has to be the first parameter of any function in the class. + """类方法""" + # self 参数是对类本身的引用,用于访问属于类的变量。 + # 它不一定是self,你可以随便叫它什么,但它必须是类中任何函数的第一个参数。 return 'Hello ' + self.name def say_goodbye(self): """Class method.""" return 'Goodbye ' + self.name - # When a class definition is entered, a new namespace is created, and used as the local scope — - # thus, all assignments to local variables go into this new namespace. In particular, function - # definitions bind the name of the new function here. + # 当输入一个类定义时,将创建一个新的命名空间,并将其用作局部作用域,所有对局部变量的赋值都将进入这个新的命名空间。 + # 特别是,函数定义在这里绑定了新函数的名称。 - # Class instantiation uses function notation. Just pretend that the class object is a - # parameterless function that returns a new instance of the class. For example the following - # code will creates a new instance of the class and assigns this object to the local variable. + # 类实例化使用函数表示法。 只需假设类对象是一个返回类的新实例的无参数函数。 + # 例如,下面的代码将创建一个类的新实例,并将该对象赋值给局部变量。 greeter = GreetingClass() assert greeter.say_hello() == 'Hello user' diff --git a/src/classes/test_class_objects.py b/src/classes/test_class_objects.py index 2d5a4cdb..ce7caaa4 100644 --- a/src/classes/test_class_objects.py +++ b/src/classes/test_class_objects.py @@ -1,77 +1,72 @@ -"""Class Definition Syntax. +"""类定义的语法. @see: https://docs.python.org/3/tutorial/classes.html#class-objects -After defining the class attributes to a class, the class object can be created by assigning the -object to a variable. The created object would have instance attributes associated with it. +定义了类的类属性后,可以通过将对象赋值给变量来创建类对象。创建的对象将具有与其关联的实例属性。 """ def test_class_objects(): - """Class Objects. + """类对象。 - Class objects support two kinds of operations: - - attribute references - - instantiation. + 类对象支持两种操作: + - 属性引用 + - 实例化 """ - # ATTRIBUTE REFERENCES use the standard syntax used for all attribute references in - # Python: obj.name. Valid attribute names are all the names that were in the class’s namespace - # when the class object was created. For class MyCounter the following references are valid - # attribute references: + # 属性引用使用Python中用于所有属性引用的标准语法: obj.name. + # 有效的属性名是创建类对象时类的命名空间中的所有名称。 + # 对于MyCounter类,以下引用是有效的属性引用: class ComplexNumber: - """Example of the complex numbers class""" + """复数类的例子""" real = 0 imaginary = 0 def get_real(self): - """Return real part of complex number.""" + """返回复数的实部。""" return self.real def get_imaginary(self): - """Return imaginary part of complex number.""" + """返回复数的虚部。""" return self.imaginary assert ComplexNumber.real == 0 - # __doc__ is also a valid attribute, returning the docstring belonging to the class - assert ComplexNumber.__doc__ == 'Example of the complex numbers class' + # __doc__ 也是一个有效的属性,返回属于类的文档字符串 + assert ComplexNumber.__doc__ == '复数类的例子' - # Class attributes can also be assigned to, so you can change the value of - # ComplexNumber.counter by assignment. + # 类属性也可以被赋值,因此可以更改 ComplexNumber 的值。计数器的任务。 ComplexNumber.real = 10 assert ComplexNumber.real == 10 - # CLASS INSTANTIATION uses function notation. Just pretend that the class object is a - # parameterless function that returns a new instance of the class. For example - # (assuming the above class): + # 类实例化使用函数表示法。只需假设类对象是一个返回类的新实例的无参数函数。例如(假设上面的类): complex_number = ComplexNumber() assert complex_number.real == 10 assert complex_number.get_real() == 10 - # Let's change counter default value back. + # 让我们把计数器的默认值改回来。 ComplexNumber.real = 10 assert ComplexNumber.real == 10 - # The instantiation operation (“calling” a class object) creates an empty object. Many classes - # like to create objects with instances customized to a specific initial state. Therefore a - # class may define a special method named __init__(), like this: + # 实例化操作(“调用”类对象)创建一个空对象。许多类喜欢创建具有自定义到特定初始状态的实例的对象。 + # 因此,类可以定义一个名为__init__()的特殊方法,像这样: class ComplexNumberWithConstructor: - """Example of the class with constructor""" + """带有构造函数的类示例""" + def __init__(self, real_part, imaginary_part): self.real = real_part self.imaginary = imaginary_part def get_real(self): - """Return real part of complex number.""" + """返回复数的实部。""" return self.real def get_imaginary(self): - """Return imaginary part of complex number.""" + """返回复数的虚部。""" return self.imaginary complex_number = ComplexNumberWithConstructor(3.0, -4.5) diff --git a/src/classes/test_inheritance.py b/src/classes/test_inheritance.py index 5884da2c..3d07fb60 100644 --- a/src/classes/test_inheritance.py +++ b/src/classes/test_inheritance.py @@ -1,15 +1,15 @@ -"""Inheritance +"""继承 @see: https://docs.python.org/3/tutorial/classes.html#inheritance -Inheritance is one of the principles of object-oriented programming. Since classes may share a lot -of the same code, inheritance allows a derived class to reuse the same code and modify accordingly +继承是面向对象编程的原则之一。 +由于类可能共享许多相同的代码,继承允许派生类重用相同的代码并相应地修改 """ # pylint: disable=too-few-public-methods class Person: - """Example of the base class""" + """基类的示例""" def __init__(self, name): self.name = name @@ -18,43 +18,37 @@ def get_name(self): return self.name -# The syntax for a derived class definition looks like this. +# 派生类定义的语法如下所示。 # pylint: disable=too-few-public-methods class Employee(Person): - """Example of the derived class + """派生类的示例 - The Base Class (in our case Person) must be defined in a scope containing the derived class - definition. In place of a base class name, other arbitrary expressions are also allowed. + 基类(在我们的例子中是 Person ) 必须在包含派生类定义的范围内定义。也允许使用其他任意表达式来代替基类名。 - Derived classes may override methods of their base classes. Because methods have no special - privileges when calling other methods of the same object, a method of a base class that calls - another method defined in the same base class may end up calling a method of a derived class - that overrides it. + 派生类可以重写其基类的方法。 + 由于方法在调用同一对象的其他方法时没有特殊特权, + 因此调用同一基类中定义的另一个方法的基类方法最终可能会调用覆盖该基类的派生类的方法。 - An overriding method in a derived class may in fact want to extend rather than simply replace - the base class method of the same name. There is a simple way to call the base class method - directly: just call BaseClassName.methodname(self, arguments). This is occasionally useful to - clients as well. (Note that this only works if the base class is accessible as BaseClassName - in the global scope.) + 派生类中的覆盖方法实际上可能希望扩展而不是简单地替换同名的基类方法。 + 有一种直接调用基类方法的简单方法:只需调用 BaseClassName.methodname(self, arguments). + 这有时对客户端也很有用。(注意,只有当基类在全局作用域中可以作为 BaseClassName 访问时,这才有效。) """ def __init__(self, name, staff_id): Person.__init__(self, name) - # You may also use super() here in order to avoid explicit using of parent class name: + # 你也可以在这里使用 super() 来避免显式使用父类名: # >>> super().__init__(name) self.staff_id = staff_id def get_full_id(self): - """Get full employee id""" + """获取完整的员工id""" return self.get_name() + ', ' + self.staff_id def test_inheritance(): - """Inheritance.""" + """继承""" - # There’s nothing special about instantiation of derived classes: DerivedClassName() creates a - # new instance of the class. Method references are resolved as follows: the corresponding class - # attribute is searched, descending down the chain of base classes if necessary, and the method - # reference is valid if this yields a function object. + # 派生类的实例化没有什么特别之处: DerivedClassName() 创建了该类的一个新实例。 + # 方法引用的解析方法如下:搜索相应的类属性,必要时沿着基类链向下查找,如果产生一个函数对象,方法引用是有效的。 person = Person('Bill') employee = Employee('John', 'A23') @@ -62,14 +56,12 @@ def test_inheritance(): assert employee.get_name() == 'John' assert employee.get_full_id() == 'John, A23' - # Python has two built-in functions that work with inheritance: + # Python 有两个与继承相关的内置函数: # - # - Use isinstance() to check an instance’s type: isinstance(obj, int) will be True only if - # obj.__class__ is int or some class derived from int. + # - 使用 isinstance() 检查实例的类型: 只有当 obj.__class__ 为 int 或 int 的派生类, instance(obj,int) 才会为 True # - # - Use issubclass() to check class inheritance: issubclass(bool, int) is True since bool is - # a subclass of int. However, issubclass(float, int) is False since float is not a subclass - # of int. + # - 使用 issubclass() 检查类继承: issubclass(bool, int) 为 True,因为 bool 是 int 的子类。 + # 然而,issubclass(float, int) 是 False,因为 float 不是 int 的子类。 assert isinstance(employee, Employee) assert not isinstance(person, Employee) diff --git a/src/classes/test_instance_objects.py b/src/classes/test_instance_objects.py index e58dc343..5b614510 100644 --- a/src/classes/test_instance_objects.py +++ b/src/classes/test_instance_objects.py @@ -1,25 +1,23 @@ -"""Class Definition Syntax. +"""类定义的语法。 @see: https://docs.python.org/3/tutorial/classes.html#instance-objects """ def test_instance_objects(): - """Instance Objects. + """实例对象。 - Now what can we do with instance objects? The only operations understood by instance objects - are attribute references. There are two kinds of valid attribute names: - - data attributes - - methods. + 现在我们可以用实例对象做什么?实例对象唯一能理解的操作是属性引用。有效的属性名有两种: + - 数据属性 + - 方法 """ - # DATA ATTRIBUTES need not be declared; like local variables, they spring into existence when - # they are first assigned to. For example, if x is the instance of MyCounter created above, - # the following piece of code will print the value 16, without leaving a trace. + # 数据属性不需要声明;像局部变量一样,它们在第一次被赋值时就会出现。 + # 例如,如果x是上面创建的MyCounter的实例,下面的代码段将打印值16,而不留下跟踪。 # pylint: disable=too-few-public-methods class DummyClass: - """Dummy class""" + """伪类""" pass dummy_instance = DummyClass() diff --git a/src/classes/test_method_objects.py b/src/classes/test_method_objects.py index 1d4e66a9..0df55548 100644 --- a/src/classes/test_method_objects.py +++ b/src/classes/test_method_objects.py @@ -1,14 +1,14 @@ -"""Class Definition Syntax. +"""类定义的语法. @see: https://docs.python.org/3/tutorial/classes.html#method-objects -Classes can have two types of attribute references: data or methods. Class methods are called -by [variable_name].[method_name]([parameters]) as opposed to class data which lacks the (). +类可以有两种类型的属性引用:数据或方法。 +类方法由[variable_name].[method_name]([parameters])调用,与缺少()的类数据相反。 """ class MyCounter: - """A simple example of the counter class""" + """计数器类的一个简单示例""" counter = 10 def get_counter(self): @@ -22,39 +22,34 @@ def increment_counter(self): def test_method_objects(): - """Method Objects.""" + """方法对象。""" - # The other kind of instance attribute reference is a method. A method is a function that - # “belongs to” an object. (In Python, the term method is not unique to class instances: other - # object types can have methods as well. For example, list objects have methods called append, - # insert, remove, sort, and so on. However, in the following discussion, we’ll use the term - # method exclusively to mean methods of class instance objects, unless explicitly stated - # otherwise.) + # 另一种实例属性引用是方法。 + # 方法是“属于”对象的函数。 + # (在Python中,方法一词不是类实例所特有的:其他对象类型也可以有方法。 + # 例如,列表对象有append、insert、remove、sort等方法。 + # 但是,在接下来的讨论中,除非另有明确说明,否则我们将使用术语方法专指类实例对象的方法。) - # But be aware that counter.get_counter() is not the same thing as MyCounter.get_counter() — - # it is a method object, not a function object. + # 但是要注意 counter。get_counter() 和 mycounter。get_counter()不是一回事 — + # 它是一个方法对象,不是一个函数对象。 - # Usually, a method is called right after it is bound + # 通常,方法在绑定后立即被调用 counter = MyCounter() assert counter.get_counter() == 10 - # However, it is not necessary to call a method right away: counter.get_counter() is a method - # object, and can be stored away and called at a later time. For example: + # 但是,没有必要立即调用一个方法: Counter.get_counter() 是一个方法对象,可以存储起来,以后再调用。 + # 例如: get_counter = counter.get_counter assert get_counter() == 10 - # What exactly happens when a method is called? You may have noticed that counter.get_counter() - # was called without an argument above, even though the function definition for get_counter() - # specified an argument (self). What happened to the argument? Surely Python raises an - # exception when a function that requires an argument is called without any — even if the - # argument isn’t actually used… - - # Actually, you may have guessed the answer: the special thing about methods is that the - # instance object is passed as the first argument of the function. In our example, the call - # counter.get_counter() is exactly equivalent to MyCounter.get_counter(counter). In general, - # calling a method with a list of n arguments is equivalent to calling the corresponding - # function with an argument list that is created by inserting the method’s instance object - # before the first argument. + # 当一个方法被调用时到底发生了什么? + # 您可能已经注意到,上面调用counter.get_counter()时没有带实参,尽管get_counter()的函数定义指定了一个实参(self)。 + # 参数发生了什么? + # 当然,当一个需要参数的函数被调用时,Python会引发异常 — 即使这个参数实际上没有被使用…… + + # 实际上,您可能已经猜到了答案:方法的特殊之处在于实例对象作为函数的第一个参数传递。 + # 在我们的示例中,调用counter.get_counter() 完全等价于 MyCounter.get_counter(counter). + # 通常,使用 n个参数列表调用一个方法等同于使用参数列表调用相应的函数,参数列表是通过在第一个参数之前插入方法的实例对象创建的。 assert counter.get_counter() == 10 assert MyCounter.get_counter(counter) == 10 diff --git a/src/classes/test_multiple_inheritance.py b/src/classes/test_multiple_inheritance.py index 2ad73f8d..d81db538 100644 --- a/src/classes/test_multiple_inheritance.py +++ b/src/classes/test_multiple_inheritance.py @@ -1,25 +1,24 @@ -"""Multiple Inheritance +"""多重继承 @see: https://docs.python.org/3/tutorial/classes.html#multiple-inheritance -Some classes may derive from multiple classes. This means that the derived class would have -its attributes, along with the attributes of all the classes that it was derived from. +有些类可能派生多个类。 这意味着派生类将具有自己的属性,以及派生它的所有类的属性。 """ def test_multiple_inheritance(): - """Multiple Inheritance""" + """多重继承""" # pylint: disable=too-few-public-methods class Clock: - """Clock class""" + """Clock 类""" time = '11:23 PM' def get_time(self): - """Get current time + """获取当前时间 - Method is hardcoded just for multiple inheritance illustration. + 方法是硬编码的,只是为了演示多重继承。 """ return self.time @@ -30,36 +29,28 @@ class Calendar: date = '12/08/2018' def get_date(self): - """Get current date + """获得当前日期 - Method is hardcoded just for multiple inheritance illustration. + 方法是硬编码的,只是为了演示多重继承。 """ return self.date - # Python supports a form of multiple inheritance as well. A class definition with multiple + # Python还支持一种形式的多重继承。包含多个的类定义 # base classes looks like this. class CalendarClock(Clock, Calendar): - """Class that uses multiple inheritance. - - For most purposes, in the simplest cases, you can think of the search for attributes i - nherited from a parent class as depth-first, left-to-right, not searching twice in the same - class where there is an overlap in the hierarchy. Thus, if an attribute is not found in - CalendarClock, it is searched for in Clock, then (recursively) in the base classes of - Clock, and if it was not found there, it was searched for in Calendar, and so on. - - In fact, it is slightly more complex than that; the method resolution order changes - dynamically to support cooperative calls to super(). This approach is known in some other - multiple-inheritance languages as call-next-method and is more powerful than the super call - found in single-inheritance languages. - - Dynamic ordering is necessary because all cases of multiple inheritance exhibit one or more - diamond relationships (where at least one of the parent classes can be accessed through - multiple paths from the bottommost class). For example, all classes inherit from object, - so any case of multiple inheritance provides more than one path to reach object. To keep - the base classes from being accessed more than once, the dynamic algorithm linearizes the - search order in a way that preserves the left-to-right ordering specified in each class, - that calls each parent only once, and that is monotonic (meaning that a class can be - subclassed without affecting the precedence order of its parents). + """使用多重继承的类。 + + 在大多数情况下,在最简单的情况下,可以将从父类继承的属性的搜索视为深度优先,从左到右,而不是在层次结构中有重叠的同一个类中搜索两次。 + 因此,如果在CalendarClock中没有找到某个属性,就在Clock中搜索它,然后(递归地)在Clock的基类中搜索它, + 如果在那里没有找到,就在Calendar中搜索它,依此类推。 + + 事实上,实际情况要稍微复杂一些;方法解析顺序会动态更改,以支持对 super() 的协作调用。 + 这种方法在其他一些多继承语言中称为“调用下一个方法”(call-next-method), + 比单继承语言中的超级调用更强大。 + + 动态排序是必要的,因为所有多重继承的情况都显示出一个或多个菱形关系(其中至少有一个父类可以从最底的类通过多个路径访问)。 + 例如,所有的类都继承自object,因此任何多重继承的情况都提供了多个到达object的路径。 + 保持不止一次被访问的基类,动态算法线性搜索顺序的方式保存每个类中指定的从左到右的顺序,每个父母只有一次调用,这是单调(也就是说,一个类可以派生子类而不影响其父母)的优先顺序。 """ calendar_clock = CalendarClock() diff --git a/src/control_flow/test_break.py b/src/control_flow/test_break.py index 42e7faa3..331f3148 100644 --- a/src/control_flow/test_break.py +++ b/src/control_flow/test_break.py @@ -1,25 +1,25 @@ -"""BREAK statement +"""break 语句 @see: https://docs.python.org/3/tutorial/controlflow.html -The break statement, like in C, breaks out of the innermost enclosing "for" or "while" loop. +break语句,就像在C中一样,打破了最内层的“for”或“while”循环。 """ def test_break_statement(): - """BREAK statement""" + """break 语句""" - # Let's terminate the loop in case if we've found the number we need in a range from 0 to 100. + # 如果我们在0到100的范围内找到了需要的数字,我们就终止循环。 number_to_be_found = 42 - # This variable will record how many time we've entered the "for" loop. + # 这个变量将记录我们输入“for”循环的次数。 number_of_iterations = 0 for number in range(100): if number == number_to_be_found: - # Break here and don't continue the loop. + # 在这里中断,不要继续循环。 break else: number_of_iterations += 1 - # We need to make sure that break statement has terminated the loop once it found the number. + # 我们需要确保break语句一旦找到编号就终止了循环。 assert number_of_iterations == 42 diff --git a/src/control_flow/test_continue.py b/src/control_flow/test_continue.py index 23c015bd..28b872df 100644 --- a/src/control_flow/test_continue.py +++ b/src/control_flow/test_continue.py @@ -1,26 +1,24 @@ -"""CONTINUE statement +"""continue 语句 @see: https://docs.python.org/3/tutorial/controlflow.html -The continue statement is borrowed from C, continues with the next iteration of the loop. +continue 语句借用自C语言,继续循环的下一个迭代。 """ def test_continue_statement(): - """CONTINUE statement in FOR loop""" + """FOR 环中的 CONTINUE 语句""" - # Let's - - # This list will contain only even numbers from the range. + # 这个列表将只包含范围中的偶数。 even_numbers = [] - # This list will contain every other numbers (in this case - ods). + # 这个列表将包含所有其他数字(在本例中是ods)。 rest_of_the_numbers = [] for number in range(0, 10): - # Check if remainder after division is zero (which would mean that number is even). + # 检查除法后余数是否为零(这意味着该数是偶数)。 if number % 2 == 0: even_numbers.append(number) - # Stop current loop iteration and go to the next one immediately. + # 停止当前循环迭代并立即转到下一个。 continue rest_of_the_numbers.append(number) diff --git a/src/control_flow/test_for.py b/src/control_flow/test_for.py index 7411277b..9df6f87d 100644 --- a/src/control_flow/test_for.py +++ b/src/control_flow/test_for.py @@ -2,45 +2,40 @@ @see: https://docs.python.org/3/tutorial/controlflow.html -The for statement in Python differs a bit from what you may be used to in C or Pascal. -Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or -giving the user the ability to define both the iteration step and halting condition (as C), -Python’s for statement iterates over the items of any sequence (a list or a string), in the -order that they appear in the sequence. For example (no pun intended): +Python 中的 for 语句与您可能在 C 或 Pascal 中使用的语句略有不同。 +Python 的 for 语句不是总是迭代数字的等差数列(如在 Pascal 中),也不是让用户能够定义迭代步骤和暂停条件(如 C), +而是迭代任何序列(列表或一个字符串),按照它们在序列中出现的顺序。例如(没有双关语意): """ # pylint: disable=too-many-locals def test_for_statement(): - """FOR statement""" + """FOR 语句""" - # Measure some strings: + # 测试一些字符串: words = ['cat', 'window', 'defenestrate'] words_length = 0 for word in words: words_length += len(word) - # "cat" length is 3 - # "window" length is 6 - # "defenestrate" length is 12 + # "cat" 长度是 3 + # "window" 长度是 6 + # "defenestrate" 长度是 12 assert words_length == (3 + 6 + 12) - # If you need to modify the sequence you are iterating over while inside the loop - # (for example to duplicate selected items), it is recommended that you first make a copy. - # Iterating over a sequence does not implicitly make a copy. The slice notation makes this - # especially convenient: - for word in words[:]: # Loop over a slice copy of the entire list. + # 如果您需要修改在循环内部迭代的序列 (例如,复制选定项),建议您先复印一份。 + # 在序列上迭代不会隐式地生成副本。 切片表示法使得这特别方便: + for word in words[:]: # 循环遍历整个列表的切片副本。 if len(word) > 6: words.insert(0, word) - # Otherwise with for w in words:, the example would attempt to create an infinite list, - # inserting defenestrate over and over again. + # 否则,这个例子将尝试创建一个无限列表,并反复插入defenestrate。 assert words == ['defenestrate', 'cat', 'window', 'defenestrate'] - # If you do need to iterate over a sequence of numbers, the built-in function range() comes in - # handy. It generates arithmetic progressions: + # 如果确实需要迭代一个数字序列,那么内置函数 range() 可以派上用场。 + # 它生成等差级数: iterated_numbers = [] for number in range(5): @@ -48,7 +43,7 @@ def test_for_statement(): assert iterated_numbers == [0, 1, 2, 3, 4] - # To iterate over the indices of a sequence, you can combine range() and len() as follows: + # 要遍历序列的索引,你可以组合 range() 和 len() 如下: words = ['Mary', 'had', 'a', 'little', 'lamb'] concatenated_string = '' @@ -58,7 +53,7 @@ def test_for_statement(): assert concatenated_string == 'Mary had a little lamb ' - # Or simply use enumerate(). + # 或者简单地使用 enumerate()。 concatenated_string = '' for word_index, word in enumerate(words): @@ -66,8 +61,7 @@ def test_for_statement(): assert concatenated_string == 'Mary had a little lamb ' - # When looping through dictionaries, the key and corresponding value can be retrieved at the - # same time using the items() method. + # 在遍历字典时,可以使用 items() 方法同时检索键和相应的值。 knights_names = [] knights_properties = [] @@ -79,8 +73,7 @@ def test_for_statement(): assert knights_names == ['gallahad', 'robin'] assert knights_properties == ['the pure', 'the brave'] - # When looping through a sequence, the position index and corresponding value can be retrieved - # at the same time using the enumerate() function + # 当循环遍历一个序列时,可以使用 enumerate() 函数同时检索位置索引和相应的值 indices = [] values = [] for index, value in enumerate(['tic', 'tac', 'toe']): @@ -90,8 +83,7 @@ def test_for_statement(): assert indices == [0, 1, 2] assert values == ['tic', 'tac', 'toe'] - # To loop over two or more sequences at the same time, the entries can be paired with - # the zip() function. + # 要同时循环两个或多个序列,可以将条目与 zip() 函数配对。 questions = ['name', 'quest', 'favorite color'] answers = ['lancelot', 'the holy grail', 'blue'] combinations = [] @@ -109,25 +101,20 @@ def test_for_statement(): def test_range_function(): """Range function - If you do need to iterate over a sequence of numbers, the built-in function range() comes in - handy. It generates arithmetic progressions. + 如果确实需要迭代一个数字序列,那么内置函数 range() 可以派上用场。 + 它产生等差级数。 - In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. - It is an object which returns the successive items of the desired sequence when you iterate - over it, but it doesn’t really make the list, thus saving space. + range() 返回的对象在很多方面都表现得像一个列表,但实际上它不是。 + 它是一个在迭代时返回所需序列的连续项的对象,但它并不真正构成列表,因此节省了空间。 - We say such an object is iterable, that is, suitable as a target for functions and constructs - that expect something from which they can obtain successive items until the supply is exhausted. - We have seen that the for statement is such an iterator. The function list() is another; it - creates lists from iterables: + 我们说这样的对象是可迭代的,也就是说,适合作为函数和构造的目标他们期望能得到一些连续的东西,直到供应耗尽。 + 我们已经看到for语句就是这样一个迭代器。函数list()是另一个; 它从可迭代对象中创建列表: """ assert list(range(5)) == [0, 1, 2, 3, 4] - # The given end point is never part of the generated sequence; range(10) generates 10 values, - # the legal indices for items of a sequence of length 10. It is possible to let the range start - # at another number, or to specify a different increment (even negative; sometimes this is - # called the ‘step’): + # 给定的终点从来不是生成序列的一部分; range(10) 生成10个值,即长度为10的序列的合法索引。 + # 可以让范围从另一个数字开始,或指定不同的增量 (甚至负数; 有时这被称为‘step’): assert list(range(5, 10)) == [5, 6, 7, 8, 9] assert list(range(0, 10, 3)) == [0, 3, 6, 9] diff --git a/src/control_flow/test_if.py b/src/control_flow/test_if.py index d512267d..3c46ffcc 100644 --- a/src/control_flow/test_if.py +++ b/src/control_flow/test_if.py @@ -1,12 +1,11 @@ -"""IF statement +"""IF 语句 @see: https://docs.python.org/3/tutorial/controlflow.html -There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is -short for ‘else if’, and is useful to avoid excessive indentation. +可以有零个或多个elif部分,else部分是可选的。 +关键字' elif '是' else if '的缩写,用于避免过度缩进。 -An if … elif … elif … sequence is a substitute for the switch or case statements found -in other languages. +在其他语言中 switch ... case 语句是 if … elif … elif … 替代品 """ diff --git a/src/control_flow/test_try.py b/src/control_flow/test_try.py index fed06f59..e06f63d5 100644 --- a/src/control_flow/test_try.py +++ b/src/control_flow/test_try.py @@ -1,22 +1,21 @@ -"""TRY statement +"""try 语句 @see: https://www.w3schools.com/python/python_try_except.asp -"try" statement is used for exception handling. -When an error occurs, or exception as we call it, Python will normally stop and generate an error -message. These exceptions can be handled using the try statement. +"try" 语句被用于异常处理. +当出现错误或我们所说的异常时,Python通常会停止并生成错误消息。这些异常可以使用try语句来处理。 -The "try" block lets you test a block of code for errors. -The "except" block lets you handle the error. -The "else" block lets you execute the code if no errors were raised. -The "finally" block lets you execute code, regardless of the result of the try- and except blocks. +“try” 块允许您测试代码块的错误。 +“except” 块允许您处理错误。 +"else" 块允许您在没有引发错误的情况下执行代码。 +“finally” 块允许您执行代码,而不管try的结果如何——除了块之外。 """ def test_try(): """TRY statement""" - # The try block will generate an error, because x is not defined: + # try块将产生一个错误,因为 not_existing_variable 没有定义: exception_has_been_caught = False try: @@ -27,8 +26,7 @@ def test_try(): assert exception_has_been_caught - # You can define as many exception blocks as you want, e.g. if you want to execute a special - # block of code for a special kind of error: + # 你可以定义任意多的异常块,例如,如果你想为一个特殊的错误执行一个特殊的代码块: exception_message = '' try: @@ -39,8 +37,7 @@ def test_try(): assert exception_message == 'Variable is not defined' - # You can use the else keyword to define a block of code to be executed - # if no errors were raised. + # 如果未引发错误,可以使用else关键字定义要执行的代码块。 message = '' # pylint: disable=broad-except try: @@ -52,8 +49,7 @@ def test_try(): assert message == 'Success.Nothing went wrong.' - # The finally block, if specified, will be executed regardless if the try block raises an - # error or not. + # 如果指定了 finally 块,则无论try块是否引发错误都将执行。 message = '' try: # pylint: undefined-variable diff --git a/src/control_flow/test_while.py b/src/control_flow/test_while.py index 4bc58028..e3571d88 100644 --- a/src/control_flow/test_while.py +++ b/src/control_flow/test_while.py @@ -1,23 +1,21 @@ -"""WHILE statement +"""while 语句 @see: https://docs.python.org/3/tutorial/controlflow.html @see: https://docs.python.org/3/reference/compound_stmts.html#the-while-statement -The while loop executes as long as the condition remains true. In Python, like in C, any -non-zero integer value is true; zero is false. The condition may also be a string or list -value, in fact any sequence; anything with a non-zero length is true, empty sequences are -false. +只要条件保持为真,while循环就会执行。 +在Python中,像在C中一样,任何非零整数值都为真;零是错误的。 +条件也可以是字符串或列表值,实际上可以是任何序列;任何长度非零的都为真,空序列为假。 -The test used in the example is a simple comparison. The standard comparison operators are -written the same as in C: < (less than), > (greater than), == (equal to), <= (less than or -equal to), >= (greater than or equal to) and != (not equal to). +示例中使用的测试是一个简单的比较。 +标准比较操作符的写法与C中相同:<(小于)、>(大于)、==(等于)、<=(小于或等于)、>=(大于或等于)和!=(不等于)。 """ def test_while_statement(): """WHILE statement""" - # Let's raise the number to certain power using while loop. + # 让我们用 while 循环将这个数提高到某个幂。 number = 2 power = 5 diff --git a/src/data_types/test_dictionaries.py b/src/data_types/test_dictionaries.py index da3b9cc8..5c98b5bf 100644 --- a/src/data_types/test_dictionaries.py +++ b/src/data_types/test_dictionaries.py @@ -1,23 +1,19 @@ -"""Dictionaries. +"""字典. @see: https://docs.python.org/3/tutorial/datastructures.html#dictionaries @see: https://www.w3schools.com/python/python_dictionaries.asp -A dictionary is a collection which is unordered, changeable and indexed. In Python dictionaries are -written with curly brackets, and they have keys and values. - -Dictionaries are sometimes found in other languages as “associative memories” or “associative -arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by -keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used -as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object -either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since -lists can be modified in place using index assignments, slice assignments, or methods like append() -and extend(). - -It is best to think of a dictionary as a set of key: value pairs, with the requirement that the -keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {}. -Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs -to the dictionary; this is also the way dictionaries are written on output. +字典是无序的、可变的和有索引的集合。 +在 Python 中,字典是用大括号写的,它们有键和值。 + +在其他语言中,词典有时被称为“联想记忆”或“联想记忆”数组”。 +与序列(由一系列数字建立索引)不同,字典通过键建立索引,键可以是任何不可变类型; +字符串和数字总是可以作为键. 如果元组只包含字符串、数字或元组,则可以用作键;如果一个元组包含任何可变对象它不能直接或间接地作为键使用. +不能将列表用作键,因为可以使用索引赋值、切片赋值或 append() 和 extend() 等方法在适当的位置修改列表。 + +最好把字典看作是一组键: 值对, 有了这个要求键是唯一的(在一个字典中)。 +一对大括号创建一个空字典:{}。 +在花括号中放置一个逗号分隔的键:值对列表,将初始键:值对添加到字典中;这也是在输出上编写字典的方式。 """ @@ -32,47 +28,44 @@ def test_dictionary(): assert isinstance(fruits_dictionary, dict) - # You may access set elements by keys. + # 你可以通过键来访问集合元素。 assert fruits_dictionary['apple'] == 'green' assert fruits_dictionary['banana'] == 'yellow' assert fruits_dictionary['cherry'] == 'red' - # To check whether a single key is in the dictionary, use the in keyword. + # 若要检查字典中是否有单个键,请使用in关键字。 assert 'apple' in fruits_dictionary assert 'pineapple' not in fruits_dictionary - # Change the apple color to "red". + # 改变苹果的颜色为“红色”。 fruits_dictionary['apple'] = 'red' - # Add new key/value pair to the dictionary + # 向字典中添加新的键值对 fruits_dictionary['pineapple'] = 'yellow' assert fruits_dictionary['pineapple'] == 'yellow' - # Performing list(d) on a dictionary returns a list of all the keys used in the dictionary, - # in insertion order (if you want it sorted, just use sorted(d) instead). + # 对一个字典执行list(d)将返回一个包含该字典中使用的所有键的列表,按插入顺序(如果您想要对其排序,只需使用sorted(d))。 assert list(fruits_dictionary) == ['cherry', 'apple', 'banana', 'pineapple'] assert sorted(fruits_dictionary) == ['apple', 'banana', 'cherry', 'pineapple'] - # It is also possible to delete a key:value pair with del. + # 也可以用del删除键值对。 del fruits_dictionary['pineapple'] assert list(fruits_dictionary) == ['cherry', 'apple', 'banana'] - # The dict() constructor builds dictionaries directly from sequences of key-value pairs. + # dict()构造函数直接从键-值对序列构建字典。 dictionary_via_constructor = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) assert dictionary_via_constructor['sape'] == 4139 assert dictionary_via_constructor['guido'] == 4127 assert dictionary_via_constructor['jack'] == 4098 - # In addition, dict comprehensions can be used to create dictionaries from arbitrary key - # and value expressions: - dictionary_via_expression = {x: x**2 for x in (2, 4, 6)} + # 此外,字典推导式可以用于从任意键和值表达式创建字典: + dictionary_via_expression = {x: x ** 2 for x in (2, 4, 6)} assert dictionary_via_expression[2] == 4 assert dictionary_via_expression[4] == 16 assert dictionary_via_expression[6] == 36 - # When the keys are simple strings, it is sometimes easier to specify pairs using - # keyword arguments. + # 当键是简单字符串时,使用关键字参数指定键对有时会更容易。 dictionary_for_string_keys = dict(sape=4139, guido=4127, jack=4098) assert dictionary_for_string_keys['sape'] == 4139 assert dictionary_for_string_keys['guido'] == 4127 diff --git a/src/data_types/test_lists.py b/src/data_types/test_lists.py index 33ffdbe9..3d53ec67 100644 --- a/src/data_types/test_lists.py +++ b/src/data_types/test_lists.py @@ -1,72 +1,66 @@ -"""Lists. +"""列表 # @see: https://www.learnpython.org/en/Lists # @see: https://docs.python.org/3/tutorial/introduction.html # @ee: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists -Python knows a number of compound data types, used to group together -other values. The most versatile is the list, which can be written as a -list of comma-separated values (items) between square brackets. Lists -might contain items of different types, but usually the items all have -the same type. +Python 知道许多用于组合的复合数据类型其他值。 +最通用的是列表,可以写成 a 方括号之间用逗号分隔的值(项)列表。 +列表可能包含不同类型的项,但通常所有项都有相同的类型. """ import pytest def test_list_type(): - """List type.""" + """列表类型.""" - # Lists are very similar to arrays. They can contain any type of variable, and they can contain - # as many variables as you wish. Lists can also be iterated over in a very simple manner. - # Here is an example of how to build a list. + # 列表非常类似于数组. 它们可以包含任何类型的变量,并且可以包含任意多的变量. + # 列表也可以以一种非常简单的方式迭代. + # 下面是一个如何构建列表的示例。 squares = [1, 4, 9, 16, 25] assert isinstance(squares, list) - # Like strings (and all other built-in sequence type), lists can be - # indexed and sliced: - assert squares[0] == 1 # indexing returns the item + # 和字符串(以及所有其他内置序列类型)一样,列表也可以被索引和切片: + assert squares[0] == 1 # 索引返回项 assert squares[-1] == 25 - assert squares[-3:] == [9, 16, 25] # slicing returns a new list + assert squares[-3:] == [9, 16, 25] # slice 返回一个新列表 - # All slice operations return a new list containing the requested elements. - # This means that the following slice returns a new (shallow) copy of - # the list: + # 所有切片操作都返回一个包含所请求元素的新列表。 + # 这意味着下面的切片返回列表的一个新(浅)副本: assert squares[:] == [1, 4, 9, 16, 25] - # Lists also support operations like concatenation: + # 列表也支持像连接这样的操作: assert squares + [36, 49, 64, 81, 100] == [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] - # Unlike strings, which are immutable, lists are a mutable type, i.e. it - # is possible to change their content: - cubes = [1, 8, 27, 65, 125] # something's wrong here, the cube of 4 is 64! - cubes[3] = 64 # replace the wrong value + # 与不可变的字符串不同,列表是一种可变类型。 + # 可以改变它们的内容: + cubes = [1, 8, 27, 65, 125] # 这里有问题,4的 3 次方是64! + cubes[3] = 64 # 替换错误的值 assert cubes == [1, 8, 27, 64, 125] - # You can also add new items at the end of the list, by using - # the append() method - cubes.append(216) # add the cube of 6 - cubes.append(7 ** 3) # and the cube of 7 + # 还可以使用append()方法在列表末尾添加新项 + cubes.append(216) # 添加 6的立方 + cubes.append(7 ** 3) # 添加 7的立方 assert cubes == [1, 8, 27, 64, 125, 216, 343] - # Assignment to slices is also possible, and this can even change the size - # of the list or clear it entirely: + # 也可以给切片赋值,这甚至可以改变列表的大小或完全清除它: letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - letters[2:5] = ['C', 'D', 'E'] # replace some values + letters[2:5] = ['C', 'D', 'E'] # 替换一些值 assert letters == ['a', 'b', 'C', 'D', 'E', 'f', 'g'] - letters[2:5] = [] # now remove them + letters[2:5] = [] # 现在删除它们 assert letters == ['a', 'b', 'f', 'g'] - # clear the list by replacing all the elements with an empty list + # 通过将所有元素替换为空列表来清除列表 letters[:] = [] assert letters == [] - # The built-in function len() also applies to lists + # 内置函数len()也适用于列表 letters = ['a', 'b', 'c', 'd'] assert len(letters) == 4 - # It is possible to nest lists (create lists containing other lists), - # for example: + # 可以嵌套列表(创建包含其他列表的列表), + # 例如: list_of_chars = ['a', 'b', 'c'] list_of_numbers = [1, 2, 3] mixed_list = [list_of_chars, list_of_numbers] @@ -76,19 +70,19 @@ def test_list_type(): def test_list_methods(): - """Test list methods.""" + """测试列表的方法。""" fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] # list.append(x) - # Add an item to the end of the list. - # Equivalent to a[len(a):] = [x]. + # 将一个项目添加到列表的末尾。 + # 相当于 a[len(a):] = [x]. fruits.append('grape') assert fruits == ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana', 'grape'] # list.remove(x) - # Remove the first item from the list whose value is equal to x. - # It raises a ValueError if there is no such item. + # 从列表中删除值为x的第一项. + # 如果没有这样的项,它将引发ValueError。 fruits.remove('grape') assert fruits == ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] @@ -96,38 +90,37 @@ def test_list_methods(): fruits.remove('not existing element') # list.insert(i, x) - # Insert an item at a given position. The first argument is the index of the element - # before which to insert, so a.insert(0, x) inserts at the front of the list, - # and a.insert(len(a), x) is equivalent to a.append(x). + # 在给定位置插入一项。 + # 第一个参数是要插入的元素的索引,所以 a.insert(0, x) 插入到列表的前面,而 a.insert(len(a), x) 等价于 a.append(x)。 fruits.insert(0, 'grape') assert fruits == ['grape', 'orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] # list.index(x[, start[, end]]) - # Return zero-based index in the list of the first item whose value is equal to x. - # Raises a ValueError if there is no such item. - # The optional arguments start and end are interpreted as in the slice notation and are used - # to limit the search to a particular subsequence of the list. The returned index is computed - # relative to the beginning of the full sequence rather than the start argument. + # 返回值为x的第一个项的列表中从0开始的索引。 + # 如果没有这样的项则引发ValueError。 + # 可选参数 start 和 end 被解释为切片表示法,用于将搜索限制为列表的特定子序列。 + # 返回计算的索引 + # 相对于整个序列的开始,而不是start参数。 assert fruits.index('grape') == 0 assert fruits.index('orange') == 1 assert fruits.index('banana') == 4 - assert fruits.index('banana', 5) == 7 # Find next banana starting a position 5 + assert fruits.index('banana', 5) == 7 # 找到下一个 banana 开始位置 5 with pytest.raises(Exception): fruits.index('not existing element') # list.count(x) - # Return the number of times x appears in the list. + # 返回 x 出现在列表中的次数。 assert fruits.count('tangerine') == 0 assert fruits.count('banana') == 2 # list.copy() - # Return a shallow copy of the list. Equivalent to a[:]. + # 返回列表的浅拷贝。 相当于 a[:]. fruits_copy = fruits.copy() assert fruits_copy == ['grape', 'orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] # list.reverse() - # Reverse the elements of the list in place. + # 将列表中的元素反向排列。 fruits_copy.reverse() assert fruits_copy == [ 'banana', @@ -141,8 +134,7 @@ def test_list_methods(): ] # list.sort(key=None, reverse=False) - # Sort the items of the list in place (the arguments can be used for sort customization, - # see sorted() for their explanation). + # 对列表中的项进行适当排序(参数可用于排序定制,请参阅 sorted() 了解它们的解释)。 fruits_copy.sort() assert fruits_copy == [ 'apple', @@ -156,27 +148,23 @@ def test_list_methods(): ] # list.pop([i]) - # Remove the item at the given position in the list, and return it. If no index is specified, - # a.pop() removes and returns the last item in the list. (The square brackets around the i in - # the method signature denote that the parameter is optional, not that you should type square - # brackets at that position.) + # 删除列表中给定位置的项,并返回它。如果没有指定索引,a.pop()将删除并返回列表中的最后一项。 + # (方法签名中i周围的方括号表示参数是可选的,而不是在那个位置输入方括号。) assert fruits == ['grape', 'orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] assert fruits.pop() == 'banana' assert fruits == ['grape', 'orange', 'apple', 'pear', 'banana', 'kiwi', 'apple'] # list.clear() - # Remove all items from the list. Equivalent to del a[:]. + # 从列表中删除所有项目。 相当于 del a[:]. fruits.clear() assert fruits == [] def test_del_statement(): - """The del statement + """del 语法 - There is a way to remove an item from a list given its index instead of its value: the del - statement. This differs from the pop() method which returns a value. The del statement can also - be used to remove slices from a list or clear the entire list (which we did earlier by - assignment of an empty list to the slice). + 有一种方法可以从列表中删除给定索引而不是值的项: del. + 这与有返回值的 pop()方法不同。 del语句还可以用于从列表中删除片或清除整个列表 (我们之前是通过给切片赋一个空列表来做的). """ numbers = [-1, 1, 66.25, 333, 333, 1234.5] @@ -190,48 +178,45 @@ def test_del_statement(): del numbers[:] assert numbers == [] - # del can also be used to delete entire variables: + # del 也可以用来删除整个变量: del numbers with pytest.raises(Exception): - # Referencing the name a hereafter is an error (at least until another - # value is assigned to it). + # 之后引用名称 numbers 是错误的 (至少在给它赋值之前是这样). assert numbers == [] # noqa: F821 def test_list_comprehensions(): - """List Comprehensions. + """列表推导式. - List comprehensions provide a concise way to create lists. Common applications are to make new - lists where each element is the result of some operations applied to each member of another - sequence or iterable, or to create a subsequence of those elements that satisfy a certain - condition. + 列表推导式提供了一种创建列表的简明方法。 常见的应用是使新列出每个元素是应用于另一个元素的每个成员的某些操作的结果序列或可迭代的, + 或创建满足一定条件的那些元素的子序列条件。 - A list comprehension consists of brackets containing an expression followed by a for clause, - then zero or more for or if clauses. The result will be a new list resulting from evaluating - the expression in the context of the for and if clauses which follow it. + 列表推导式由括号组成,括号中包含一个表达式,后面跟着一个 for 子句,然后零个或多个 for 或 if 子句。 + 结果将是一个新的列表,它是在表达式后面的 for 和 if 子句的上下文中对表达式求值而得到的。 """ - # For example, assume we want to create a list of squares, like: + # 例如,假设我们想要创建一个正方形列表, + # 请注意,这将创建(或覆盖)一个名为“number”的变量,该变量在循环完成后仍然存在。 + # 例如: squares = [] for number in range(10): squares.append(number ** 2) assert squares == [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] - # Note that this creates (or overwrites) a variable named "number" that still exists after - # the loop completes. We can calculate the list of squares without any side effects using: + # 我们可以在没有任何副作用的情况下计算方块列表: squares = list(map(lambda x: x ** 2, range(10))) assert squares == [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] - # or, equivalently (which is more concise and readable): + # 或者,同样的(更简洁易读): squares = [x ** 2 for x in range(10)] assert squares == [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] - # For example, this listcomp combines the elements of two lists if they are not equal. + # 例如,如果两个列表的元素不相等,这个 listcomp 将组合它们。 combinations = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y] assert combinations == [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] - # and it’s equivalent to: + # 它等价于 combinations = [] for first_number in [1, 2, 3]: for second_number in [3, 1, 4]: @@ -240,57 +225,54 @@ def test_list_comprehensions(): assert combinations == [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] - # Note how the order of the for and if statements is the same in both these snippets. + # 注意,这两个代码片段中的for和if语句的顺序是相同的. - # If the expression is a tuple (e.g. the (x, y) in the previous example), - # it must be parenthesized. + # 如果表达式是一个元组(例如前面例子中的(x, y)),则必须用圆括号括起来。 - # Let's see some more examples: + # 让我们来看更多的例子: vector = [-4, -2, 0, 2, 4] - # Create a new list with the values doubled. + # 创建一个值翻倍的新列表。 doubled_vector = [x * 2 for x in vector] assert doubled_vector == [-8, -4, 0, 4, 8] - # Filter the list to exclude negative numbers. + # 过滤列表以排除负数。 positive_vector = [x for x in vector if x >= 0] assert positive_vector == [0, 2, 4] - # Apply a function to all the elements. + # 对所有元素应用一个函数。 abs_vector = [abs(x) for x in vector] assert abs_vector == [4, 2, 0, 2, 4] - # Call a method on each element. + # 对每个元素调用一个方法。 fresh_fruit = [' banana', ' loganberry ', 'passion fruit '] clean_fresh_fruit = [weapon.strip() for weapon in fresh_fruit] assert clean_fresh_fruit == ['banana', 'loganberry', 'passion fruit'] - # Create a list of 2-tuples like (number, square). + # 创建一个2元组列表,如(number, square). square_tuples = [(x, x ** 2) for x in range(6)] assert square_tuples == [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] - # Flatten a list using a listcomp with two 'for'. + # 使用带有两个 for 的列表组合使列表变平. vector = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] flatten_vector = [num for elem in vector for num in elem] assert flatten_vector == [1, 2, 3, 4, 5, 6, 7, 8, 9] def test_nested_list_comprehensions(): - """Nested List Comprehensions - - The initial expression in a list comprehension can be any arbitrary expression, including - another list comprehension. + """嵌套列表推导式1 + 列表推导式中的初始表达式可以是任意表达式,包括另一个corrrmprehension列表。 """ - # Consider the following example of a 3x4 matrix implemented as a list of 3 lists of length 4: + # 考虑下面这个3x4矩阵的例子,它是一个由3个长度为4的列表组成的列表: matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], ] - # The following list comprehension will transpose rows and columns: + # 下面的列表推导式将对行和列进行转置: transposed_matrix = [[row[i] for row in matrix] for i in range(4)] assert transposed_matrix == [ [1, 5, 9], @@ -299,8 +281,7 @@ def test_nested_list_comprehensions(): [4, 8, 12], ] - # As we saw in the previous section, the nested listcomp is evaluated in the context of the - # for that follows it, so this example is equivalent to: + # 正如我们在前一节中看到的,嵌套的listcomp是在它后面的for上下文中求值的, 所以这个例子相当于: transposed = [] for i in range(4): transposed.append([row[i] for row in matrix]) @@ -312,10 +293,10 @@ def test_nested_list_comprehensions(): [4, 8, 12], ] - # which, in turn, is the same as: + # 反过来,也就是: transposed = [] for i in range(4): - # the following 3 lines implement the nested listcomp + # 下面的3行实现了嵌套的listcomp transposed_row = [] for row in matrix: transposed_row.append(row[i]) @@ -328,8 +309,8 @@ def test_nested_list_comprehensions(): [4, 8, 12], ] - # In the real world, you should prefer built-in functions to complex flow statements. - # The zip() function would do a great job for this use case: + # 在现实世界中,您应该更喜欢内置函数而不是复杂的流语句。 + # zip()函数可以很好地完成这个用例: assert list(zip(*matrix)) == [ (1, 5, 9), (2, 6, 10), diff --git a/src/data_types/test_numbers.py b/src/data_types/test_numbers.py index 66bb111c..ae579cda 100644 --- a/src/data_types/test_numbers.py +++ b/src/data_types/test_numbers.py @@ -1,9 +1,9 @@ -"""Numbers. +"""数字. @see: https://docs.python.org/3/tutorial/introduction.html @see: https://www.w3schools.com/python/python_numbers.asp -There are three numeric types in Python: +Python中有三种数值类型: - int (e.g. 2, 4, 20) - bool (e.g. False and True, acting like 0 and 1) - float (e.g. 5.0, 1.6) @@ -14,8 +14,7 @@ def test_integer_numbers(): """Integer type - Int, or integer, is a whole number, positive or negative, - without decimals, of unlimited length. + Int或integer是一个整数,无论正或负,没有小数,无限长. """ positive_integer = 1 @@ -30,11 +29,9 @@ def test_integer_numbers(): def test_booleans(): """Boolean - Booleans represent the truth values False and True. The two objects representing the values - False and True are the only Boolean objects. The Boolean type is a subtype of the integer type, - and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the - exception being that when converted to a string, the strings "False" or "True" are returned, - respectively. + 布尔值表示真值False和True。表示值的两个对象False和True是唯一的布尔对象。 + 布尔类型是整数类型的子类型,和布尔值的行为类似于值0和1,在几乎所有上下文中 + 例外是当转换为字符串时,返回字符串"False"或"True" """ true_boolean = True @@ -46,7 +43,7 @@ def test_booleans(): assert isinstance(true_boolean, bool) assert isinstance(false_boolean, bool) - # Let's try to cast boolean to string. + # 让我们尝试将布尔类型转换为字符串。 assert str(true_boolean) == "True" assert str(false_boolean) == "False" @@ -54,12 +51,11 @@ def test_booleans(): def test_float_numbers(): """Float type - Float, or "floating point number" is a number, positive or negative, - containing one or more decimals. + 浮点数,或“浮点数”是一个数,无论正或负,包含一个或多个小数的 """ float_number = 7.0 - # Another way of declaring float is using float() function. + # 另一种声明浮点数的方法是使用float()函数。 float_number_via_function = float(7) float_negative = -35.59 @@ -68,8 +64,7 @@ def test_float_numbers(): assert isinstance(float_number_via_function, float) assert isinstance(float_negative, float) - # Float can also be scientific numbers with an "e" to indicate - # the power of 10. + # Float也可以是用“e”表示的科学数字 10 的幂。 float_with_small_e = 35e3 float_with_big_e = 12E4 @@ -80,7 +75,7 @@ def test_float_numbers(): def test_complex_numbers(): - """Complex Type""" + """复数型""" complex_number_1 = 5 + 6j complex_number_2 = 3 - 2j @@ -91,30 +86,29 @@ def test_complex_numbers(): def test_number_operators(): - """Basic operations""" + """ 基本运算""" - # Addition. + # 加法. assert 2 + 4 == 6 - # Multiplication. + # 乘法. assert 2 * 4 == 8 - # Division always returns a floating point number. + # 除法总是返回浮点数. assert 12 / 3 == 4.0 assert 12 / 5 == 2.4 assert 17 / 3 == 5.666666666666667 - # Modulo operator returns the remainder of the division. + # 取模运算符返回除法的余数. assert 12 % 3 == 0 assert 13 % 3 == 1 - # Floor division discards the fractional part. + # 除法向下取整摒弃了小数部分. assert 17 // 3 == 5 - # Raising the number to specific power. - assert 5 ** 2 == 25 # 5 squared - assert 2 ** 7 == 128 # 2 to the power of 7 + # 把数字提高到特定的幂。 + assert 5 ** 2 == 25 # 5的平方 + assert 2 ** 7 == 128 # 2的7次方 - # There is full support for floating point; operators with - # mixed type operands convert the integer operand to floating point. + # 运算符与混合类型操作数将整数操作数转换为浮点数。 assert 4 * 3.75 - 1 == 14.0 diff --git a/src/data_types/test_sets.py b/src/data_types/test_sets.py index 1dfb1329..1f0505c4 100644 --- a/src/data_types/test_sets.py +++ b/src/data_types/test_sets.py @@ -1,13 +1,12 @@ -"""Sets. +""" Set. @see: https://www.w3schools.com/python/python_sets.asp @see: https://docs.python.org/3.7/tutorial/datastructures.html#sets -A set is a collection which is unordered and unindexed. -In Python sets are written with curly brackets. +set 是无序且无索引的集合。 +在 Python 中,集合是用花括号写的. -Set objects also support mathematical operations like union, intersection, difference, and -symmetric difference. +集合对象还支持数学运算,如并、交、差和对称差。 """ @@ -17,8 +16,8 @@ def test_sets(): assert isinstance(fruits_set, set) - # It is also possible to use the set() constructor to make a set. - # Note the double round-brackets + # 也可以使用set()构造函数来创建集合。 + # 注意双圆括号 fruits_set_via_constructor = set(("apple", "banana", "cherry")) assert isinstance(fruits_set_via_constructor, set) @@ -29,42 +28,42 @@ def test_set_methods(): fruits_set = {"apple", "banana", "cherry"} - # You may check if the item is in set by using "in" statement + # 你可以使用“in”语句检查项目是否已设置 assert "apple" in fruits_set assert "pineapple" not in fruits_set - # Use the len() method to return the number of items. + # 使用len()方法返回项的数量。 assert len(fruits_set) == 3 - # You can use the add() object method to add an item. + # 您可以使用add()对象方法来添加一个项目. fruits_set.add("pineapple") assert "pineapple" in fruits_set assert len(fruits_set) == 4 - # Use remove() method to remove an item. + # 使用remove()方法删除一个条目。 fruits_set.remove("pineapple") assert "pineapple" not in fruits_set assert len(fruits_set) == 3 - # Demonstrate set operations on unique letters from two word: + # 演示对两个单词中唯一字母的集合操作: first_char_set = set('abracadabra') second_char_set = set('alacazam') - assert first_char_set == {'a', 'r', 'b', 'c', 'd'} # unique letters in first word - assert second_char_set == {'a', 'l', 'c', 'z', 'm'} # unique letters in second word + assert first_char_set == {'a', 'r', 'b', 'c', 'd'} # 第一个单词的唯一字母 + assert second_char_set == {'a', 'l', 'c', 'z', 'm'} # 第二个单词中唯一的字母 - # Letters in first word but not in second. + # 字母在第一个单词中,但不在第二个单词中。 assert first_char_set - second_char_set == {'r', 'b', 'd'} - # Letters in first word or second word or both. + # 第一个单词或第二个单词或两个单词中的字母。 assert first_char_set | second_char_set == {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} - # Common letters in both words. + # 两个单词中常见的字母。 assert first_char_set & second_char_set == {'a', 'c'} - # Letters in first or second word but not both. + # 字母出现在第一个或第二个单词中,但不能同时出现在两个单词中。 assert first_char_set ^ second_char_set == {'r', 'd', 'b', 'm', 'z', 'l'} - # Similarly to list comprehensions, set comprehensions are also supported: + # 与列表推导式类似,集合推导式也支持: word = {char for char in 'abracadabra' if char not in 'abc'} assert word == {'r', 'd'} diff --git a/src/data_types/test_strings.py b/src/data_types/test_strings.py index ae86432f..22f5b4c3 100644 --- a/src/data_types/test_strings.py +++ b/src/data_types/test_strings.py @@ -1,77 +1,69 @@ -"""Strings. +"""字符串. @see: https://docs.python.org/3/tutorial/introduction.html @see: https://www.w3schools.com/python/python_strings.asp @see: https://www.w3schools.com/python/python_ref_string.asp -Besides numbers, Python can also manipulate strings, which can be -expressed in several ways. They can be enclosed in single quotes ('...') -or double quotes ("...") with the same result. +除了数字,Python还可以操作字符串,可以是 +用几种方式表达。它们可以用单引号括起来('…') +或者双引号(“…”),结果相同。 """ import pytest def test_string_type(): - """String type""" + """字符串类型""" - # String with double quotes. + # 双引号字符串。 name_1 = "John" - # String with single quotes. + # 带有单引号的字符串。 name_2 = 'John' - # Strings created with different kind of quotes are treated the same. + # 使用不同类型的引号创建的字符串被视为相同的。 assert name_1 == name_2 assert isinstance(name_1, str) assert isinstance(name_2, str) - # \ can be used to escape quotes. - # use \' to escape the single quote or use double quotes instead. + # \ 可以用来转义引号。 + # 使用\'转义单引号或使用双引号代替。 single_quote_string = 'doesn\'t' double_quote_string = "doesn't" assert single_quote_string == double_quote_string - # \n means newline. + # \ n表示换行符。 multiline_string = 'First line.\nSecond line.' - # Without print(), \n is included in the output. - # But with print(), \n produces a new line. + # 如果没有print(),输出中将包含\n。 + # 但是使用print(), \n会产生一个新行。 assert multiline_string == 'First line.\nSecond line.' - # Strings can be indexed, with the first character having index 0. - # There is no separate character type; a character is simply a string - # of size one. Note that since -0 is the same as 0, negative indices - # start from -1. + # 字符串可以被索引,第一个字符的索引为0。 + # 没有单独的字符类型;一个字符就是一个字符串的大小。请注意,因为-0和0是相同的,所以负索引从1开始。 word = 'Python' - assert word[0] == 'P' # First character. - assert word[5] == 'n' # Fifth character. - assert word[-1] == 'n' # Last character. - assert word[-2] == 'o' # Second-last character. - assert word[-6] == 'P' # Sixth from the end or zeroth from the beginning. + assert word[0] == 'P' # 首位字符 + assert word[5] == 'n' # 第 6个字符。 + assert word[-1] == 'n' # 最后一个字符. + assert word[-2] == 'o' # 倒数第二个的字符。 + assert word[-6] == 'P' # 倒数第六个 或 正数第1个字符. assert isinstance(word[0], str) - # In addition to indexing, slicing is also supported. While indexing is - # used to obtain individual characters, slicing allows you to obtain - # substring: - assert word[0:2] == 'Py' # Characters from position 0 (included) to 2 (excluded). - assert word[2:5] == 'tho' # Characters from position 2 (included) to 5 (excluded). + # 除了索引之外,还支持切片. 虽然索引用来获取个别字符,切片可以让您获取子字符串: + assert word[0:2] == 'Py' # 从位置0(包括)到位置2(不包括)的字符. + assert word[2:5] == 'tho' # 位置2(包括)至位置5(不包括)的字符. - # Note how the start is always included, and the end always excluded. - # This makes sure that s[:i] + s[i:] is always equal to s: + # 注意开头总是包含在内,而结尾总是被排除在外. + # 这确保了s[:i] + s[i:]总是等于s: assert word[:2] + word[2:] == 'Python' assert word[:4] + word[4:] == 'Python' - # Slice indices have useful defaults; an omitted first index defaults to - # zero, an omitted second index defaults to the size of the string being - # sliced. - assert word[:2] == 'Py' # Character from the beginning to position 2 (excluded). - assert word[4:] == 'on' # Characters from position 4 (included) to the end. - assert word[-2:] == 'on' # Characters from the second-last (included) to the end. - - # One way to remember how slices work is to think of the indices as - # pointing between characters, with the left edge of the first character - # numbered 0. Then the right edge of the last character of a string of n - # characters has index n, for example: + # 切片索引具有有用的缺省值; 省略的第一个索引默认为0,被省略的第二索引默认为字符串的大小切片. + assert word[:2] == 'Py' # 字符从开始到位置2(不包括). + assert word[4:] == 'on' # 从位置4(包括)到末尾的字符. + assert word[-2:] == 'on' # 字符从倒数第二(包括)到结尾. + + # 记住切片是如何工作的一种方法是把指标看作指向字符之间的,具有第一个字符的左边缘的 + # 编号0. 然后是字符串n的最后一个字符的右边缘例如,字符的索引为n: # # +---+---+---+---+---+---+ # | P | y | t | h | o | n | @@ -79,34 +71,32 @@ def test_string_type(): # 0 1 2 3 4 5 6 # -6 -5 -4 -3 -2 -1 - # Attempting to use an index that is too large will result in an error. + # 试图使用一个太大的索引将导致一个错误。 with pytest.raises(Exception): not_existing_character = word[42] assert not not_existing_character - # However, out of range slice indexes are handled gracefully when used - # for slicing: + # 但是,在使用范围外的片索引时,使用切片会得到很好的处理: assert word[4:42] == 'on' assert word[42:] == '' - # Python strings cannot be changed — they are immutable. Therefore, - # assigning to an indexed position in the string - # results in an error: + # Python字符串不能被改变——它们是不可变的。因此,对字符串中的索引位置赋值会导致错误: with pytest.raises(Exception): # pylint: disable=unsupported-assignment-operation word[0] = 'J' - # If you need a different string, you should create a new one: + # 如果您需要一个不同的字符串,您应该创建一个新的: assert 'J' + word[1:] == 'Jython' assert word[:2] + 'py' == 'Pypy' - # The built-in function len() returns the length of a string: + # 内置函数len()返回字符串的长度: characters = 'supercalifragilisticexpialidocious' assert len(characters) == 34 - # String literals can span multiple lines. One way is using triple-quotes: """...""" - # or '''...'''. End of lines are automatically included in the string, but it’s possible - # to prevent this by adding a \ at the end of the line. The following example: + # 字符串字面值可以跨多行。一种方法是使用三引号: """...""" 或 '''...'''. + # 字符串中自动包含行结束符,但可以通过在行结束符中添加\来防止这种情况。 + # + # 下面的例子: multi_line_string = '''\ First line Second line @@ -119,119 +109,111 @@ def test_string_type(): def test_string_operators(): - """Basic operations + """ 基本运算 - Strings can be concatenated (glued together) with the + operator, - and repeated with *: 3 times 'un', followed by 'ium' + 字符串可以用 + 操作符连接(粘在一起),并用 * 重复连接3次 'un',接着是'ium' """ assert 3 * 'un' + 'ium' == 'unununium' # 'Py' 'thon' - python = 'Py' 'thon' + python = 'Py''thon' assert python == 'Python' - # This feature is particularly useful when you want to break long strings: + # 当您想要中断长字符串时,这个特性特别有用: text = ( 'Put several strings within parentheses ' 'to have them joined together.' ) assert text == 'Put several strings within parentheses to have them joined together.' - # If you want to concatenate variables or a variable and a literal, use +: + # 如果你想要连接变量或者一个变量和一个字面值,使用+: prefix = 'Py' assert prefix + 'thon' == 'Python' def test_string_methods(): - """String methods""" + """字符串的方法""" hello_world_string = "Hello, World!" - # The strip() method removes any whitespace from the beginning or the end. + # strip()方法从开头或结尾删除任何空格. string_with_whitespaces = " Hello, World! " assert string_with_whitespaces.strip() == "Hello, World!" - # The len() method returns the length of a string. + # len()方法返回字符串的长度. assert len(hello_world_string) == 13 - # The lower() method returns the string in lower case. + # lower()方法返回小写的字符串. assert hello_world_string.lower() == 'hello, world!' - # The upper() method returns the string in upper case. + # upper()方法以大写形式返回字符串. assert hello_world_string.upper() == 'HELLO, WORLD!' - # The replace() method replaces a string with another string. + # replace()方法将一个字符串替换为另一个字符串. assert hello_world_string.replace('H', 'J') == 'Jello, World!' - # The split() method splits the string into substrings if it finds instances of the separator. + # 如果找到分隔符实例,split()方法将字符串分割成子字符串. assert hello_world_string.split(',') == ['Hello', ' World!'] - # Converts the first character to upper case + # 将第一个字符转换为大写 assert 'low letter at the beginning'.capitalize() == 'Low letter at the beginning' - # Returns the number of times a specified value occurs in a string. + # 返回指定值在字符串中出现的次数. assert 'low letter at the beginning'.count('t') == 4 - # Searches the string for a specified value and returns the position of where it was found. + # 在字符串中搜索指定的值并返回找到它的位置. assert 'Hello, welcome to my world'.find('welcome') == 7 - # Converts the first character of each word to upper case + # 将每个单词的第一个字符转换为大写 assert 'Welcome to my world'.title() == 'Welcome To My World' - # Returns a string where a specified value is replaced with a specified value. + # 返回一个字符串,其中指定的值被替换为指定的值。 assert 'I like bananas'.replace('bananas', 'apples') == 'I like apples' - # Joins the elements of an iterable to the end of the string. + # 将可迭代对象的元素连接到字符串的末尾. my_tuple = ('John', 'Peter', 'Vicky') assert ', '.join(my_tuple) == 'John, Peter, Vicky' - # Returns True if all characters in the string are upper case. + # 如果字符串中的所有字符都是大写,则返回True. assert 'ABC'.isupper() assert not 'AbC'.isupper() - # Check if all the characters in the text are letters. + # 检查文本中的所有字符是否都是字母. assert 'CompanyX'.isalpha() assert not 'Company 23'.isalpha() - # Returns True if all characters in the string are decimals. + # 如果字符串中的所有字符都是数字,则返回True. assert '1234'.isdecimal() assert not 'a21453'.isdecimal() def test_string_formatting(): - """String formatting. + """字符串格式化. - Often you’ll want more control over the formatting of your output than simply printing - space-separated values. There are several ways to format output + 通常情况下,比起简单地打印,您希望对输出的格式有更多的控制空格分隔的值。有几种方法可以格式化输出 """ - # To use formatted string literals, begin a string with f or F before the opening quotation - # mark or triple quotation mark. Inside this string, you can write a Python expression - # between { and } characters that can refer to variables or literal values. + # 若要使用格式化字符串字面值,请在字符串的开始引号或三引号之前以 F 或 f 开头。 + # 在这个字符串内部,你可以在 { and } 字符之间编写一个 Python 表达式,它可以引用变量或文字值。 year = 2018 event = 'conference' assert f'Results of the {year} {event}' == 'Results of the 2018 conference' - # The str.format() method of strings requires more manual effort. You’ll still use { and } to - # mark where a variable will be substituted and can provide detailed formatting directives, - # but you’ll also need to provide the information to be formatted. - yes_votes = 42_572_654 # equivalent of 42572654 - no_votes = 43_132_495 # equivalent of 43132495 + # 字符串的str.format()方法需要更多的手动操作。 您仍将使用{ and }来标记变量将被替换的位置,并可以提供详细的格式化指令, + # 但是您还需要提供要格式化的信息。 + yes_votes = 42_572_654 # 相当于 42572654 + no_votes = 43_132_495 # 相当于 43132495 percentage = yes_votes / (yes_votes + no_votes) assert '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage) == ' 42572654 YES votes 49.67%' - # When you don’t need fancy output but just want a quick display of some variables for debugging - # purposes, you can convert any value to a string with the repr() or str() functions. The str() - # function is meant to return representations of values which are fairly human-readable, while - # repr() is meant to generate representations which can be read by the interpreter (or will - # force a SyntaxError if there is no equivalent syntax). For objects which don’t have a - # particular representation for human consumption, str() will return the same value as repr(). - # Many values, such as numbers or structures like lists and dictionaries, have the same - # representation using either function. Strings, in particular, have two distinct - # representations. + # 当您不需要花哨的输出,而只想快速显示一些用于调试的变量时,可以使用repr()或str()函数将任何值转换为字符串。 + # str()函数的目的是返回值的表示,这些值是相当可读的, 而 repr() 的目的是生成解释器可以读取的表示(或者如果没有等效的语法,将强制SyntaxError)。 + # 对于没有特定表示供人类使用的对象,str()将返回与repr()相同的值。. + # 许多值,如数字或像列表和字典这样的结构,使用这两个函数都有相同的表示。 + # 特别是字符串,有两种不同的表示形式。 greeting = 'Hello, world.' first_num = 10 * 3.25 @@ -239,24 +221,19 @@ def test_string_formatting(): assert str(greeting) == 'Hello, world.' assert repr(greeting) == "'Hello, world.'" - assert str(1/7) == '0.14285714285714285' + assert str(1 / 7) == '0.14285714285714285' - # The argument to repr() may be any Python object: + # repr()的参数可以是任何Python对象: assert repr((first_num, second_num, ('spam', 'eggs'))) == "(32.5, 40000, ('spam', 'eggs'))" - # Formatted String Literals - - # Formatted string literals (also called f-strings for short) let you include the value of - # Python expressions inside a string by prefixing the string with f or F and writing - # expressions as {expression}. + # 格式化的字符串 - # An optional format specifier can follow the expression. This allows greater control over how - # the value is formatted. The following example rounds pi to three places after the decimal. + # 格式化字符串字面值(也简称f-strings)可以让你在字符串前加上f或f,并将表达式写成{expression},从而将 Python 表达式的值包含在字符串中。 + # 表达式后面可以有一个可选的格式说明符. 这允许对如何格式化值进行更大的控制. 下面的示例将圆周率四舍五入到小数点后三位。 pi_value = 3.14159 assert f'The value of pi is {pi_value:.3f}.' == 'The value of pi is 3.142.' - # Passing an integer after the ':' will cause that field to be a minimum number of characters - # wide. This is useful for making columns line up: + # 在':'后面传递一个整数将使该字段成为最小字符数宽。 这对于使列对齐很有用: table_data = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} table_string = '' for name, phone in table_data.items(): @@ -266,19 +243,17 @@ def test_string_formatting(): 'Jack ==> 4098' 'Dcab ==> 7678') - # The String format() Method + # String format()方法 - # Basic usage of the str.format() method looks like this: + # str.format()方法的基本用法如下: assert 'We are {} who say "{}!"'.format('knights', 'Ni') == 'We are knights who say "Ni!"' - # The brackets and characters within them (called format fields) are replaced with the objects - # passed into the str.format() method. A number in the brackets can be used to refer to the - # position of the object passed into the str.format() method + # 方括号和其中的字符(称为格式字段)被传递到str.format()方法中的对象替换。 + # 括号中的数字可以用来引用传递给str.format()方法的对象的位置 assert '{0} and {1}'.format('spam', 'eggs') == 'spam and eggs' assert '{1} and {0}'.format('spam', 'eggs') == 'eggs and spam' - # If keyword arguments are used in the str.format() method, their values are referred to by - # using the name of the argument. + # 如果关键字参数在str.format()方法中使用,则通过参数的名称引用它们的值。 formatted_string = 'This {food} is {adjective}.'.format( food='spam', adjective='absolutely horrible' @@ -286,7 +261,7 @@ def test_string_formatting(): assert formatted_string == 'This spam is absolutely horrible.' - # Positional and keyword arguments can be arbitrarily combined + # 位置参数和关键字参数可以任意组合 formatted_string = 'The story of {0}, {1}, and {other}.'.format( 'Bill', 'Manfred', @@ -295,16 +270,15 @@ def test_string_formatting(): assert formatted_string == 'The story of Bill, Manfred, and Georg.' - # If you have a really long format string that you don’t want to split up, it would be nice if - # you could reference the variables to be formatted by name instead of by position. This can be - # done by simply passing the dict and using square brackets '[]' to access the keys + # 如果你有一个很长的格式字符串,你不想拆分,如果你可以引用变量的名称,而不是位置。 + # 这可以通过简单地传递字典并使用方括号'[]'来访问键来实现 table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} formatted_string = 'Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; Dcab: {0[Dcab]:d}'.format(table) assert formatted_string == 'Jack: 4098; Sjoerd: 4127; Dcab: 8637678' - # This could also be done by passing the table as keyword arguments with the ‘**’ notation. + # 这也可以通过使用“**”作为关键字参数传递表来实现。 formatted_string = 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table) assert formatted_string == 'Jack: 4098; Sjoerd: 4127; Dcab: 8637678' diff --git a/src/data_types/test_tuples.py b/src/data_types/test_tuples.py index b122824e..8805d8a4 100644 --- a/src/data_types/test_tuples.py +++ b/src/data_types/test_tuples.py @@ -1,21 +1,20 @@ -"""Tuples. +""" 元组. @see: https://www.w3schools.com/python/python_tuples.asp @see: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences -A tuple is a collection which is ordered and unchangeable. In Python tuples are written with -round brackets. +元组是有序且不可更改的集合。 在Python中,元组是用圆括弧。 -The Tuples have following properties: -- You cannot change values in a tuple. -- You cannot remove items in a tuple. +元组有以下属性: +- 不能更改元组中的值。 +- 不能删除元组中的项。 """ import pytest def test_tuples(): - """Tuples""" + """ 元组""" fruits_tuple = ("apple", "banana", "cherry") assert isinstance(fruits_tuple, tuple) @@ -23,63 +22,59 @@ def test_tuples(): assert fruits_tuple[1] == "banana" assert fruits_tuple[2] == "cherry" - # You cannot change values in a tuple. + # 不能更改元组中的值。 with pytest.raises(Exception): # pylint: disable=unsupported-assignment-operation fruits_tuple[0] = "pineapple" - # It is also possible to use the tuple() constructor to make a tuple (note the double - # round-brackets). - # The len() function returns the length of the tuple. + # 也可以使用 tuple() 构造函数来创建一个元组 (注意两个圆括号)。 + # len()函数返回元组的长度。 fruits_tuple_via_constructor = tuple(("apple", "banana", "cherry")) assert isinstance(fruits_tuple_via_constructor, tuple) assert len(fruits_tuple_via_constructor) == 3 - # It is also possible to omit brackets when initializing tuples. + # 初始化元组时也可以省略括号。 another_tuple = 12345, 54321, 'hello!' assert another_tuple == (12345, 54321, 'hello!') - # Tuples may be nested: + # 元组可以嵌套: nested_tuple = another_tuple, (1, 2, 3, 4, 5) assert nested_tuple == ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) - # As you see, on output tuples are always enclosed in parentheses, so that nested tuples are - # interpreted correctly; they may be input with or without surrounding parentheses, although - # often parentheses are necessary anyway (if the tuple is part of a larger expression). It is - # not possible to assign to the individual items of a tuple, however it is possible to create - # tuples which contain mutable objects, such as lists. + # 如您所见,在输出时元组总是括在括号中,因此嵌套的元组是正确解读; + # 它们的输入可以带或不带圆括号,尽管圆括号通常是必须的(如果元组是一个更大的表达式的一部分). + # 不能为元组的单个项赋值,但是可以创建包含可变对象的元组,比如列表。 - # A special problem is the construction of tuples containing 0 or 1 items: the syntax has some - # extra quirks to accommodate these. Empty tuples are constructed by an empty pair of - # parentheses; a tuple with one item is constructed by following a value with a comma (it is - # not sufficient to enclose a single value in parentheses). Ugly, but effective. For example: + # 一个特殊的问题是包含0或1项的元组的构造: 语法有一些额外的怪癖来适应这些。 + # 空元组由一对空括号构成; + # 只有一项的元组是通过在值后面加逗号来构造的(将单个值括在圆括号中是不够的). + # 丑,但有效。例如: empty_tuple = () # pylint: disable=len-as-condition assert len(empty_tuple) == 0 # pylint: disable=trailing-comma-tuple - singleton_tuple = 'hello', # <-- note trailing comma + singleton_tuple = 'hello', # <-- 注意后面的逗号 assert len(singleton_tuple) == 1 assert singleton_tuple == ('hello',) - # The following example is called tuple packing: + # 下面的例子被称为元组打包: packed_tuple = 12345, 54321, 'hello!' - # The reverse operation is also possible. + # 反向操作也是可以的。 first_tuple_number, second_tuple_number, third_tuple_string = packed_tuple assert first_tuple_number == 12345 assert second_tuple_number == 54321 assert third_tuple_string == 'hello!' - # This is called, appropriately enough, sequence unpacking and works for any sequence on the - # right-hand side. Sequence unpacking requires that there are as many variables on the left - # side of the equals sign as there are elements in the sequence. Note that multiple assignment - # is really just a combination of tuple packing and sequence unpacking. + # 这被称为序列解包,并适用于右边的任何序列。 + # 序列解包要求等号左边的变量数量与序列中的元素数量相等。 + # 请注意,多重赋值实际上只是元组打包和序列解包的组合。 - # Swapping using tuples. - # Data can be swapped from one variable to another in python using - # tuples. This eliminates the need to use a 'temp' variable. + # 交换使用元组。 + # 数据可以在 python 中使用 + # 元组。这样就不需要使用'temp'变量了。 first_number = 123 second_number = 456 first_number, second_number = second_number, first_number diff --git a/src/data_types/test_type_casting.py b/src/data_types/test_type_casting.py index e5b1fef3..827ef404 100644 --- a/src/data_types/test_type_casting.py +++ b/src/data_types/test_type_casting.py @@ -1,27 +1,22 @@ -"""Type casting. +"""类型转换 @see: https://www.w3schools.com/python/python_casting.asp -There may be times when you want to specify a type on to a variable. This can be done with casting. -Python is an object-orientated language, and as such it uses classes to define data types, -including its primitive types. +有时您可能希望为变量指定类型。这可以通过转换来实现。 +Python是一种面向对象的语言,因此它使用类来定义数据类型, 包括它的基本类型。 -Casting in python is therefore done using constructor functions: +因此 python 中的类型转换是使用构造函数来完成的: -- int() - constructs an integer number from an integer literal, a float literal (by rounding down -to the previous whole number) literal, or a string literal (providing the string represents a -whole number) +- int() - 从一个整数字面值、一个浮点字面值(通过四舍五入)构造一个整数到前一个整数)字面值,或字符串字面值(提供字符串表示整数) -- float() - constructs a float number from an integer literal, a float literal or a string literal -(providing the string represents a float or an integer) +- float() - 从整数字面值、浮点字面值或字符串字面值(提供表示浮点数或整数的字符串)构造浮点数 -- str() - constructs a string from a wide variety of data types, including strings, integer -literals and float literals +- str() - 从各种数据类型构造字符串,包括字符串、整型字面值和浮点字面值 """ def test_type_casting_to_integer(): - """Type casting to integer""" + """类型转换为整数""" assert int(1) == 1 assert int(2.8) == 2 @@ -29,7 +24,7 @@ def test_type_casting_to_integer(): def test_type_casting_to_float(): - """Type casting to float""" + """类型转换为浮点数""" assert float(1) == 1.0 assert float(2.8) == 2.8 @@ -38,7 +33,7 @@ def test_type_casting_to_float(): def test_type_casting_to_string(): - """Type casting to string""" + """类型转换为字符串""" assert str("s1") == 's1' assert str(2) == '2' diff --git a/src/exceptions/test_handle_exceptions.py b/src/exceptions/test_handle_exceptions.py index 342561a3..e28898ae 100644 --- a/src/exceptions/test_handle_exceptions.py +++ b/src/exceptions/test_handle_exceptions.py @@ -1,103 +1,96 @@ -"""Errors and Exceptions. +"""错误和异常。 @see: https://docs.python.org/3/tutorial/errors.html#errors-and-exceptions -Even if a statement or expression is syntactically correct, it may cause an error when an attempt -is made to execute it. Errors detected during execution are called exceptions and are not -unconditionally fatal. +即使一个语句或表达式在语法上是正确的,在尝试执行它时也可能会导致错误。 +在执行过程中检测到的错误称为异常,并不是无条件致命的。 -It is possible to write programs that handle selected exceptions. +编写处理选定异常的程序是可能的。 """ def test_handle_exceptions(): """Handling of exceptions - The try statement works as follows. + try语句的工作原理如下。 - - First, the try clause (the statement(s) between the try and except keywords) is executed. + - 首先,执行try子句(try和except关键字之间的语句)。 - - If no exception occurs, the except clause is skipped and execution of the try statement - is finished. + - 如果没有异常发生,则跳过except子句,并结束try语句的执行。 - - If an exception occurs during execution of the try clause, the rest of the clause is skipped. - Then if its type matches the exception named after the except keyword, the except clause is - executed, and then execution continues after the try statement. + - 如果在try子句执行期间发生异常,则跳过子句的其余部分。 + 然后,如果它的类型与except关键字后面命名的异常匹配,则执行except子句,然后在try语句之后继续执行。 - - If an exception occurs which does not match the exception named in the except clause, it is - passed on to outer try statements; if no handler is found, it is an unhandled exception and - execution stops with a message. + - 如果发生了与except子句中指定的异常不匹配的异常,则将其传递给外部的try语句; + 如果没有找到处理程序,则这是一个未处理的异常,执行将以一条消息停止。 """ - # Let's simulate division by zero exception. + # 让我们来模拟除零异常。 exception_has_been_handled = False try: - result = 10 * (1 / 0) # division by zero - # We should not get here at all. + result = 10 * (1 / 0) # 除以零 + # 我们根本就不该来这里。 assert result except ZeroDivisionError: - # We should get here because of division by zero. + # 我们应该到这里,因为除以0。 exception_has_been_handled = True assert exception_has_been_handled - # Let's simulate undefined variable access exception. + # 让我们模拟未定义变量访问异常。 exception_has_been_handled = False try: # pylint: disable=undefined-variable - result = 4 + spam * 3 # name 'spam' is not defined - # We should not get here at all. + result = 4 + spam * 3 # 名称“spam”没有定义 + # 我们根本就不该来这里。 assert result except NameError: - # We should get here because of division by zero. exception_has_been_handled = True assert exception_has_been_handled - # A try statement may have more than one except clause, to specify handlers for different - # exceptions. At most one handler will be executed. Handlers only handle exceptions that occur - # in the corresponding try clause, not in other handlers of the same try statement. An except - # clause may name multiple exceptions as a parenthesized tuple, for example: + # 一个try语句可以有多个except子句,用于指定不同异常的处理程序。 + # 最多将执行一个处理程序。处理程序只处理相应的try子句中发生的异常,而不处理同一try语句的其他处理程序中发生的异常。 + # except子句可以将多个异常命名为带括号的元组,例如: exception_has_been_handled = False try: result = 10 * (1 / 0) # division by zero - # We should not get here at all. + # 我们根本就不该来这里。 assert result except (ZeroDivisionError, NameError): - # We should get here because of division by zero. + # 我们应该到这里,因为除以0。 exception_has_been_handled = True assert exception_has_been_handled - # Exception handlers may be chained. + # 异常处理程序可以被链接。 exception_has_been_handled = False try: - result = 10 * (1 / 0) # division by zero - # We should not get here at all. + result = 10 * (1 / 0) # 除以零 + # 我们根本就不该来这里。 assert result except NameError: - # We should get here because of division by zero. + # 我们应该到这里,因为除以0。 exception_has_been_handled = True except ZeroDivisionError: - # We should get here because of division by zero. + # 我们应该到这里,因为除以0。 exception_has_been_handled = True assert exception_has_been_handled - # The try … except statement has an optional else clause, which, when present, must follow all - # except clauses. It is useful for code that must be executed if the try clause does not raise - # an exception. For example: + # try…except语句有一个可选的else子句,当它出现时,必须跟在所有except子句后面。 + # 对于在try子句没有引发异常时必须执行的代码,它是有用的。例如: exception_has_been_handled = False no_exceptions_has_been_fired = False try: result = 10 - # We should not get here at all. + # 我们根本就不该来这里。 assert result except NameError: - # We should get here because of division by zero. + # 我们应该到这里,因为除以0。 exception_has_been_handled = True else: no_exceptions_has_been_fired = True diff --git a/src/exceptions/test_raise_exceptions.py b/src/exceptions/test_raise_exceptions.py index 3d5ede1c..9bdb0dea 100644 --- a/src/exceptions/test_raise_exceptions.py +++ b/src/exceptions/test_raise_exceptions.py @@ -1,24 +1,23 @@ -"""Raising Exceptions. +"""提高异常。 @see: https://docs.python.org/3/tutorial/errors.html#raising-exceptions -The raise statement allows the programmer to force a specified exception to occur. +raise 语句允许程序员强制发生指定的异常。 """ def test_raise_exception(): - """Raising Exceptions. + """提高异常。 - The raise statement allows the programmer to force a specified exception to occur. + raise语句允许程序员强制发生指定的异常。 """ exception_is_caught = False try: - # The sole argument to raise indicates the exception to be raised. This must be either an - # exception instance or an exception class (a class that derives from Exception). If an - # exception class is passed, it will be implicitly instantiated by calling its constructor - # with no arguments - raise NameError('HiThere') # shorthand for 'raise ValueError()' + # 要引发的唯一参数表示要引发的异常。 + # 这必须是异常实例或异常类(派生自exception的类)。 + # 如果传递了一个异常类,它将通过调用不带参数的构造函数隐式实例化 + raise NameError('HiThere') # 'raise ValueError()'的简写 except NameError: exception_is_caught = True @@ -26,24 +25,23 @@ def test_raise_exception(): def test_user_defined_exception(): - """User-defined Exceptions""" + """用户自定义异常""" - # Programs may name their own exceptions by creating a new exception class. Exceptions should - # typically be derived from the Exception class, either directly or indirectly. - # Most exceptions are defined with names that end in “Error,” similar to the naming of the - # standard exceptions. Many standard modules define their own exceptions to report errors - # that may occur in functions they define. + # 程序可以通过创建一个新的异常类来命名自己的异常。 + # 异常通常应该直接或间接地派生自Exception类。 + # 大多数异常的名称都以“Error”结尾,类似于标准异常的命名。 + # 许多标准模块定义了它们自己的异常,以报告它们定义的函数中可能发生的错误。 class MyCustomError(Exception): - """Example of MyCustomError exception.""" + """MyCustomError异常示例。""" + def __init__(self, message): super().__init__(message) self.message = message - custom_exception_is_caught = False - try: raise MyCustomError('My custom message') except MyCustomError: + custom_exception_is_caught = True assert custom_exception_is_caught diff --git a/src/files/test_file_methods.py b/src/files/test_file_methods.py index e2684472..52988185 100644 --- a/src/files/test_file_methods.py +++ b/src/files/test_file_methods.py @@ -1,44 +1,43 @@ -"""Methods of File Objects +"""文件对象的方法 @see: https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects -Reading from a file does not always have to be sequential. There are methods to look for -specific locations in the file, much like flipping to a page in a book. +从文件中读取并不总是顺序的。 +有一些方法可以查找文件中的特定位置, +就像翻到一本书的某一页一样。 """ def test_file_methods(): - """Methods of File Objects""" + """文件对象的方法""" multi_line_file = open('src/files/multi_line_file.txt', 'r') binary_file = open('src/files/binary_file', 'r') - # To read a file’s contents, call f.read(size), which reads some quantity of data and returns - # it as a string (in text mode) or bytes object (in binary mode). size is an optional numeric - # argument. When size is omitted or negative, the entire contents of the file will be read and - # returned; it’s your problem if the file is twice as large as your machine’s memory. Otherwise, - # at most size bytes are read and returned. If the end of the file has been reached, f.read() - # will return an empty string (''). + # 要读取文件的内容,调用f.read(size),它读取一定量的数据并将其作为字符串(文本模式)或字节对象(二进制模式)返回。 + # size是一个可选的数字参数。 + # 当size被省略或为负值时,将读取并返回文件的全部内容; + # 如果文件的大小是机器内存的两倍,那就是你的问题了。 + # 否则,最多读取并返回size字节。 + # 如果已经到达文件的末尾,f.read()将返回一个空字符串("). read_data = multi_line_file.read() # pylint: disable=duplicate-code assert read_data == 'first line\nsecond line\nthird line' - # To change the file object’s position, use f.seek(offset, from_what). The position is computed - # from adding offset to a reference point; the reference point is selected by the from_what - # argument. A from_what value of 0 measures from the beginning of the file, 1 uses the current - # file position, and 2 uses the end of the file as the reference point. from_what can be omitted - # and defaults to 0, using the beginning of the file as the reference point. - assert binary_file.seek(0) == 0 # Go to the 0th byte in the file - assert binary_file.seek(6) == 6 # Go to the 6th byte in the file + # 要改变文件对象的位置,使用f.s seek(offset, from_what)。 + # 位置从添加offset到参考点计算;参考点由from_what参数选择。 + # from_what值为0表示从文件的开头开始,1使用当前文件位置,2使用文件的结尾作为参考点。 + # From_what可以省略,默认值为0,使用文件的开头作为参考点。 + assert binary_file.seek(0) == 0 # 转到文件的第0个字节 + assert binary_file.seek(6) == 6 # 转到文件中的第6个字节 assert binary_file.read(1) == '6' - # f.readline() reads a single line from the file; a newline character (\n) is left at the end - # of the string, and is only omitted on the last line of the file if the file doesn’t end in a - # newline. This makes the return value unambiguous; if f.readline() returns an empty string, - # the end of the file has been reached, while a blank line is represented by '\n', a string - # containing only a single newline. + # readline()从文件中读取一行; + # 换行符(\n)将留在字符串的末尾,如果文件不以换行符结束,则只在文件的最后一行省略。 + # 这使得返回值没有歧义;如果f.readline()返回一个空字符串,则表示已经到达文件的末尾, + # 而空行由'\n'表示,这是一个只包含一个换行符的字符串。 multi_line_file.seek(0) assert multi_line_file.readline() == 'first line\n' diff --git a/src/files/test_file_reading.py b/src/files/test_file_reading.py index 7a36a489..cbbf36d4 100644 --- a/src/files/test_file_reading.py +++ b/src/files/test_file_reading.py @@ -1,48 +1,43 @@ -"""Reading and Writing Files +"""读写文件 @see: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files -The process of reading and writing to a file is like finding a book and opening a book. -First, the file is located, opened to the first page, then reading/writing begins until it reaches -the end of the file. +读取和写入文件的过程就像找到一本书然后打开一本书。 +首先,定位文件,打开到第一页,然后读写开始,直到到达文件的末尾。 """ def test_files_open(): - """Open files + """打开文件 - open() returns a file object, and is most commonly used with two arguments: - open(filename, mode). + open() 返回一个文件对象,最常用的是带两个参数: open (filename, mode)。 - The first argument is a string containing the filename. The second argument is another string - containing a few characters describing the way in which the file will be used. mode can be: + 第一个参数是一个包含文件名的字符串。 + 第二个参数是另一个字符串,其中包含一些描述文件使用方式的字符。 + 模式可以是: - - 'r' when the file will only be read, - - 'w' for only writing (an existing file with the same name will be erased), - - 'a' opens the file for appending; any data written to the file is automatically added to end. - - 'r+' opens the file for both reading and writing. + - 'r' 当文件只被读取时, + - 'w' 对于仅写(将删除同名的现有文件), + - 'a' 打开附加文件;写入文件的任何数据都会自动添加到文件末尾。 + - 'r+' 打开文件进行读写。 - The mode argument is optional; 'r' will be assumed if it’s omitted. + mode 参数是可选的; 如果省略,将假定为'r'。 - Normally, files are opened in text mode, that means, you read and write strings from and to the - file, which are encoded in a specific encoding. If encoding is not specified, the default is - platform dependent (see open()). 'b' appended to the mode opens the file in binary mode: now - the data is read and written in the form of bytes objects. This mode should be used for all - files that don’t contain text. + 通常,文件以文本模式打开,这意味着您从文件中读取和写入字符串,这些字符串以特定的编码方式编码。 + 如果没有指定编码,默认值是平台相关的(参见open())。 + 附加到 mode的'b'以二进制模式打开文件:现在数据以字节对象的形式读取和写入。 + 这种模式应该用于所有不包含文本的文件。 - In text mode, the default when reading is to convert platform-specific line endings (\n on - Unix, \r\n on Windows) to just \n. When writing in text mode, the default is to convert - occurrences of \n back to platform-specific line endings. This behind-the-scenes modification - to file data is fine for text files, but will corrupt binary data like that in JPEG or EXE - files. Be very careful to use binary mode when reading and writing such files. + 在文本模式下,读取时的默认值是将平台特定的行结束符(在Unix上是\n,在Windows上是\r\n)转换为仅\n。 + 当以文本模式写入时,默认是将出现的\n转换回特定于平台的行结束符。这种对文件数据的幕后修改对于文本文件来说没问题, + 但是会破坏JPEG或EXE文件中的二进制数据。在读写这类文件时,要非常小心地使用二进制模式。 - It is good practice to use the with keyword when dealing with file objects. The advantage is - that the file is properly closed after its suite finishes, even if an exception is raised at - some point. Using with is also much shorter than writing equivalent try-finally blocks: + 在处理文件对象时,最好使用with关键字。这样做的好处是,即使在某个时刻引发了异常,文件在套件结束后也会被正确地关闭。 + 与写等效的try-finally块相比,Using with 要短得多: """ - # Open files without using 'with' statement. - file = open('src/files/multi_line_file.txt', 'r') + # 不使用'with'语句打开文件。 + file = open('multi_line_file.txt', 'r') assert not file.closed @@ -58,8 +53,8 @@ def test_files_open(): assert file.closed - # Open file using with. - with open('src/files/multi_line_file.txt', 'r') as file: + # 使用with打开文件。 + with open('multi_line_file.txt', 'r') as file: read_data = file.read() assert read_data == ( @@ -70,8 +65,6 @@ def test_files_open(): assert file.closed - # If you’re not using the with keyword, then you should call f.close() to close the file and - # immediately free up any system resources used by it. If you don’t explicitly close a file, - # Python’s garbage collector will eventually destroy the object and close the open file for you, - # but the file may stay open for a while. Another risk is that different Python implementations - # will do this clean-up at different times. + # 如果你不使用 with 关键字,那么你应该调用f.close()关闭文件, 并立即释放它使用的任何系统资源。如果你不显式地关闭一个文件, + # Python 的垃圾收集器将最终销毁该对象并为你关闭打开的文件,但该文件可能会保持打开一段时间。 + # 另一个风险是,不同的Python实现将在不同的时间进行这种清理。 diff --git a/src/functions/test_function_annotations.py b/src/functions/test_function_annotations.py index 4c6495e6..d02d567b 100644 --- a/src/functions/test_function_annotations.py +++ b/src/functions/test_function_annotations.py @@ -1,27 +1,23 @@ -"""Function Annotations. +"""函数注释。 @see: https://docs.python.org/3/tutorial/controlflow.html#function-annotations -Function annotations are completely optional metadata information about the types used -by user-defined functions. +函数注释是关于用户定义函数使用的类型的完全可选的元数据信息。 -Annotations are stored in the __annotations__ attribute of the function as a dictionary and have no -effect on any other part of the function. Parameter annotations are defined by a colon after the -parameter name, followed by an expression evaluating to the value of the annotation. Return -annotations are defined by a literal ->, followed by an expression, between the parameter list and -the colon denoting the end of the def statement. +注释作为字典存储在函数的__annotations__属性中,对函数的任何其他部分都没有影响。 参数注释通过参数名称后面的冒号定义,后面是求值为注释值的表达式。 +返回注释由文字定义 ->, 后面是一个表达式,在形参表和表示 def 语句结束的冒号之间。 """ def breakfast(ham: str, eggs: str = 'eggs') -> str: """Breakfast creator. - This function has a positional argument, a keyword argument, and the return value annotated. + 这个函数有一个位置参数、一个关键字参数和带注释的返回值。 """ return ham + ' and ' + eggs def test_function_annotations(): - """Function Annotations.""" + """函数注释。""" assert breakfast.__annotations__ == {'eggs': str, 'ham': str, 'return': str} diff --git a/src/functions/test_function_arbitrary_arguments.py b/src/functions/test_function_arbitrary_arguments.py index b3f36627..f2971988 100644 --- a/src/functions/test_function_arbitrary_arguments.py +++ b/src/functions/test_function_arbitrary_arguments.py @@ -1,31 +1,27 @@ -"""Arbitrary Argument Lists +"""任意的参数列表 @see: https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists -Function can be called with an arbitrary number of arguments. These arguments will be wrapped up in -a tuple. Before the variable number of arguments, zero or more normal arguments may occur. +函数可以使用任意数量的参数来调用。这些参数将封装在一个元组中。 +在可变数量的参数之前,可能会出现零个或多个普通参数。 """ def test_function_arbitrary_arguments(): - """Arbitrary Argument Lists""" + """任意的参数列表""" - # When a final formal parameter of the form **name is present, it receives a dictionary - # containing all keyword arguments except for those corresponding to a formal parameter. - # This may be combined with a formal parameter of the form *name which receives a tuple - # containing the positional arguments beyond the formal parameter list. - # (*name must occur before **name.) For example, if we define a function like this: + # 当出现 **name 的最后一个正式形参时,它将接收一个字典,其中包含除与正式形参对应的关键字参数外的所有关键字参数。 + # 这可以与 *name 的形式参数结合使用,该形式参数接收一个包含形式参数列表之外的位置参数的元组。 + # (*name 必须出现在 **name之前。)例如,如果我们这样定义一个函数: def test_function(first_param, *arguments): - """This function accepts its arguments through "arguments" tuple amd keywords dictionary.""" + """这个函数通过“arguments”元组和关键字字典接受它的参数。""" assert first_param == 'first param' assert arguments == ('second param', 'third param') test_function('first param', 'second param', 'third param') - # Normally, these variadic arguments will be last in the list of formal parameters, because - # they scoop up all remaining input arguments that are passed to the function. Any formal - # parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that - # they can only be used as keywords rather than positional arguments. + # 通常,这些可变参数将位于形参列表的最后,因为它们将获取传递给函数的所有剩余输入参数。 + # 任何出现在*args形参之后的形式形参都是“仅关键字”参数,这意味着它们只能作为关键字而不是位置参数使用。 def concat(*args, sep='/'): return sep.join(args) diff --git a/src/functions/test_function_decorators.py b/src/functions/test_function_decorators.py index 1603a5ff..05c1c5e9 100644 --- a/src/functions/test_function_decorators.py +++ b/src/functions/test_function_decorators.py @@ -1,43 +1,49 @@ -"""Function Decorators. +"""函数修饰符。 @see: https://www.thecodeship.com/patterns/guide-to-python-function-decorators/ -Function decorators are simply wrappers to existing functions. In the context of design patterns, -decorators dynamically alter the functionality of a function, method or class without having to -directly use subclasses. This is ideal when you need to extend the functionality of functions that -you don't want to modify. We can implement the decorator pattern anywhere, but Python facilitates -the implementation by providing much more expressive features and syntax for that. +函数装饰器只是现有函数的包装器。 +在设计模式的上下文中,装饰器动态地改变函数、方法或类的功能,而不必直接使用子类。 +当您需要扩展不想修改的函数的功能时,这是理想的。 +我们可以在任何地方实现装饰器模式,但 Python 通过提供更具表达性的特性和语法来促进实现。 """ def test_function_decorators(): - """Function Decorators.""" + """函数修饰符。""" - # Function decorators are simply wrappers to existing functions. Putting the ideas mentioned - # above together, we can build a decorator. In this example let's consider a function that - # wraps the string output of another function by p tags. + # 函数装饰器只是现有函数的包装器。把上面提到的想法放在一起,我们就可以建立一个装饰。 + # 在本例中,让我们考虑一个函数,它通过 p 标记包装另一个函数的字符串输出。 - # This is the function that we want to decorate. + # 这就是我们想要装饰的功能。 def greeting(name): return "Hello, {0}!".format(name) - # This function decorates another functions output with
tag. + # 这个函数用
标记修饰了另一个函数的输出。 def decorate_with_p(func): def function_wrapper(name): return "
{0}
".format(func(name)) + return function_wrapper - # Now, let's call our decorator and pass the function we want decorate to it. + # 现在,让我们调用装饰器,并将我们想要装饰的函数传递给它。 my_get_text = decorate_with_p(greeting) - # Here we go, we've just decorated the function output without changing the function itself. + # 开始吧,我们只是修饰了函数的输出,而没有改变函数本身。 + # 执行过程: + # my_get_text('John') + # -> decorate_with_p(greeting('John')) + # -> function_wrapper('John') + # -> "{0}
".format(greeting('John')) + # -> "{0}
".format("Hello, {0}!".format('John')) + # -> 'Hello, John!
' + assert my_get_text('John') == 'Hello, John!
' # With decorator. assert greeting('John') == 'Hello, John!' # Without decorator. - # Now, Python makes creating and using decorators a bit cleaner and nicer for the programmer - # through some syntactic sugar There is a neat shortcut for that, which is to mention the - # name of the decorating function before the function to be decorated. The name of the - # decorator should be prepended with an @ symbol. + # 现在,Python通过一些语法上的“糖果”让程序员创建和使用装饰器变得更干净、更好。 + # 对此,有一个简洁的快捷方式,就是在要装饰的函数之前提到装饰函数的名称。 + # 装饰器的名称应该以@符号作为前缀。 @decorate_with_p def greeting_with_p(name): @@ -45,19 +51,17 @@ def greeting_with_p(name): assert greeting_with_p('John') == 'Hello, John!
' - # Now let's consider we wanted to decorate our greeting function by one more functions to wrap a - # div the string output. + # 现在,让我们考虑一下,我们想要通过多一个函数来装饰我们的greeting函数,以包装字符串输出的div。 - # This will be our second decorator. + # 这是我们的第二个装饰器。 def decorate_with_div(func): def function_wrapper(text): return "Hello, John!