Browse Source

update link of api comment and format

Signed-off-by: Ting Wang <kathy.wangting@huawei.com>
pull/94/head
Ting Wang 4 years ago
parent
commit
d053487faf
2 changed files with 143 additions and 100 deletions
  1. +76
    -55
      security/coding_guild_python_en.md
  2. +67
    -45
      security/coding_guild_python_zh_cn.md

+ 76
- 55
security/coding_guild_python_en.md View File

@@ -1,17 +1,17 @@
<!-- TOC -->
[Note](#note)
- [Note](#note)
- [Scope](#scope)
- [Code Style](#1-code-style)
- [Naming](#11-naming)
- [Format](#12-format)
- [Comment](#13-comment)
- [Log](#14-log)
- [General Coding](#2-general-coding)
- [Interface Declaration](#21-interface-declaration)
- [Data Verification](#22-data-verification)
- [Abnormal Behavior](#23-abnormal-behavior)
- [Serialization and Deserialization](#24-serialization-and-deserialization)
- [1. Code Style](#1-code-style)
- [1.1 Naming](#11-naming)
- [1.2 Format](#12-format)
- [1.3 Comment](#13-comment)
- [1.4 Log](#14-log)
- [2. General Coding](#2-general-coding)
- [2.1 Interface Declaration](#21-interface-declaration)
- [2.2 Data Verification](#22-data-verification)
- [2.3 Abnormal Behavior](#23-abnormal-behavior)
- [2.4 Serialization and Deserialization](#24-serialization-and-deserialization)
<!-- /TOC -->
@@ -26,14 +26,13 @@ MindSpore open source community
------------------------
### 1. Code Style
### <a name="psf">1. Code Style</a>
#### 1.1 Naming
#### <a name="pnm">1.1 Naming</a>
**Rule 1.1.1 Package names and module names are in lowercase and cannot contain underscores (_).**
##### Rule 1.1.1 Package names and module names are in lowercase and cannot contain underscores (_).
##### Rule 1.1.2 Class names are in the CamelCase style. The first letter must be capitalized, and the prefix is a private class underscore (_).
**Rule 1.1.2 Class names are in the CamelCase style. The first letter must be capitalized, and the prefix is a private class underscore (_).**
```python
class _Foo:
@@ -41,34 +40,34 @@ class _Foo:
pass
```
##### Rule 1.1.3 Function names and variable names are in lowercase and separated by underscores (_) when containing multiple words.
**Rule 1.1.3 Function names and variable names are in lowercase and separated by underscores (_) when containing multiple words.**
```python
def _func_example(path):
pass
```
##### Recommendation 1.1.4 Do not use single-character names except for iterators and counters.
**Recommendation 1.1.4 Do not use single-character names except for iterators and counters.**
#### <a name="pcs">1.2 Format</a>
#### 1.2 Format
##### Rule 1.2.1 Ensure that each line contains a maximum of 120 characters.
**Rule 1.2.1 Ensure that each line contains a maximum of 120 characters.**
If a line contains more than 120 characters, start a new line properly.
If a line contains more than 120 characters, start a new line properly.
##### Rule 1.2.2 Use spaces to indent, four at a time. Tab indent is forbidden.
**Rule 1.2.2 Use spaces to indent, four at a time. Tab indent is forbidden.**
##### Rule 1.2.3 The import sequence is as follows: standard library, third-party, and customization module.
**Rule 1.2.3 The import sequence is as follows: standard library, third-party, and customization module.**
##### Rule 1.2.4 Do not use parentheses in return statements and conditional statements.
**Rule 1.2.4 Do not use parentheses in return statements and conditional statements.**
##### Rule 1.2.5 There are two blank lines between a module-level function and a class, and one blank line between class member functions. Add blank lines between comments and code as needed. In principle, there should be no more than two blank lines.
**Rule 1.2.5 There are two blank lines between a module-level function and a class, and one blank line between class member functions. Add blank lines between comments and code as needed. In principle, there should be no more than two blank lines.**
##### Rule 1.2.6 Delete invalid or redundant code directly. Do not retain the code in the form of comments or TODO. You are advised to submit an issue record.
**Rule 1.2.6 Delete invalid or redundant code directly. Do not retain the code in the form of comments or TODO. You are advised to submit an issue record.**
#### <a name="pns">1.3 Comment</a>
#### 1.3 Comment
##### Rule 1.3.1 File header comments must contain copyright statements.
**Rule 1.3.1 File header comments must contain copyright statements.**
All Python files must contain the following copyright statements:
@@ -99,59 +98,64 @@ import xxx
> Files created in 2020 should contain `Copyright 2020 Huawei Technologies Co., Ltd`.
> Files created in 2019 and modified in 2020 should contain `Copyright 2019-2020 Huawei Technologies Co., Ltd`.
##### Rule 1.3.2 Comply with the comment formats of external classes, methods, operators, and cells:
**Rule 1.3.2 Comply with the comment formats of external classes, methods, operators, and cells:**
- The comment formats of `class` and `def` are the same. Use Python comments which is generally accepted by the industry, and indent the comments under a declaration. All `class` and `def`should be commented. You can write only one introduction for the classes and methods in the module.
- For details about the comment formats, see [MindSpore Comment Specifications](https://gitlab.huawei.com/mindspore/docs/wikis/Python-API%E6%B3%A8%E9%87%8A%E8%A7%84%E8%8C%83).
- For details about the comment formats, see [MindSpore Comment Specifications](https://gitee.com/mindspore/community/blob/master/security/comments_specification_en.md).
##### Rule 1.3.3 Do not use comments to mask Pylint alarms.
**Rule 1.3.3 Do not use comments to mask Pylint alarms.**
#### <a name="pls">1.4 Log</a>
#### 1.4 Log
##### Rule 1.4.1 Capitalize the first letter of the exception log text.
**Rule 1.4.1 Capitalize the first letter of the exception log text.**
##### Rule 1.4.2 Variable names in log texts must be marked with single quotation marks.
**Rule 1.4.2 Variable names in log texts must be marked with single quotation marks.**
### <a name="pcc">2. General Coding</a>
### 2. General Coding
#### <a name="pif">2.1 Interface Declaration</a>
#### 2.1 Interface Declaration
##### Rule 2.1.1 User interfaces are described in __all__ of a file, and __all__ is placed between import and code.
**Rule 2.1.1 User interfaces are described in __all__ of a file, and __all__ is placed between import and code.**
##### Rule 2.1.2 Use underscores (_) to prefixe the non-external methods used by the current file. Method names used across modules do not need underscore prefixes. User interfaces are declared in __all__ of a file.
**Rule 2.1.2 Use underscores (_) to prefixe the non-external methods used by the current file. Method names used across modules do not need underscore prefixes. User interfaces are declared in __all__ of a file.**
#### <a name="pdc">2.2 Data Verification</a>
#### 2.2 Data Verification
##### Rule 2.2.1 Check the validity of all external data, including but not limited to function input parameters, external input named lines, file formats, file sizes, environment variables, and user data.
**Rule 2.2.1 Check the validity of all external data, including but not limited to function input parameters, external input named lines, file formats, file sizes, environment variables, and user data.**
##### Recommendation 2.2.2 File paths must be canonicalized before use.
**Recommendation 2.2.2 File paths must be canonicalized before use.**
A file path that comes from external data must be canonicalized first. If the file path is not canonicalized, attackers can construct a malicious file path to access the file without authorization.
For example, an attacker can construct ../../../etc/passwd to access any file.
For example, use the realpath() function in Linux and the PathCanonicalize() function in Windows for file path canonicalization.
[Noncompliant Code Example]
The following code obtains the file name from an external system, concatenates the file name into a file path, and directly reads the file content. As a result, the attacker can read the content of any file.
```python
The following is an example of error code:
```
[Compliant Code Example]
Canonicalize the file path and then check whether the path is valid in the program.
```python
The following is an example of correct code:
```
[Exceptions]
Command line programs that run on the console, or file paths that are manually entered on the console are exempted from this rule.
##### Rule 2.2.3 Do not invoke the OS command parser to run commands or programs.
**Rule 2.2.3 Do not invoke the OS command parser to run commands or programs.**
If untrusted input that is not verified is used as a parameter or part of a system command, vulnerability may occur in a command injection. For the command injection vulnerability, the command is executed at the same privilege level as the Python application. It provides a function similar to shells for attackers. In Python, os.system or os.popen is often used to call a new process. If the command to be executed comes from external input, command and parameter injection may occur.
When running the command, pay attention to the following points:
1. Do not concatenate the input parameters in the character string for command execution. If the input parameters must be concatenated, perform whitelist filtering on the input parameters.
2. Verify the type of the input parameters. For example, integer data can be mandatorily converted into integers.
3. Ensure that the formatted string is correct. For example, use %d instead of %s to concatenate parameters of the int type.
[Noncompliant Code Example 1]
The attacker can find the value of the environment variable APPHOME and place the attacking program against the constant INITCMD in the corresponding directory
The attacker can find the value of the environment variable APPHOME and place the attacking program against the constant INITCMD in the corresponding directory
to execute the attack.
```python
@@ -183,11 +187,15 @@ c:\\dbms\\*.* ":
except Exception as ex:
print('exception:', ex)
```
Attackers can run the following command to exploit this vulnerability:
```python
python test.py ". && echo bad"
```
Actually, the following two commands are executed:
```python
ls .
echo bad
@@ -195,6 +203,7 @@ Actually, the following two commands are executed:
[Compliant Code Example]
Do not use os.system. You can use standard APIs instead of running system commands to complete the tasks.
```python
import os
import sys
@@ -204,13 +213,14 @@ Do not use os.system. You can use standard APIs instead of running system comman
print(ex)
```
#### <a name="pex">2.3 Abnormal Behavior</a>
#### 2.3 Abnormal Behavior
##### Rule 2.3.1 Exceptions must be properly handled. Do not suppress or ignore exceptions found in the check results.
**Rule 2.3.1 Exceptions must be properly handled. Do not suppress or ignore exceptions found in the check results.**
Ensure that the programs in each except block continue to operate only when they are valid. The except block must either recover from an exception or throw another exception suitable for the context of the current catch block to allow the most adjacent outer try-except statement block to recover.
[Compliant Code Example]
The correct method is to avoid using os.system. You can use standard APIs instead of running system commands to complete the tasks.
```python
validFlag = False
while not validFlag:
@@ -222,15 +232,18 @@ The correct method is to avoid using os.system. You can use standard APIs instea
import traceback
traceback.print_exc()
```
[Exceptions]
[Exceptions]
1. If the resource release failure does not affect the subsequent program behavior, the exception that occurs during resource release can be suppressed. Examples of releasing resources include closing files, network sockets, threads, and so on. These resources are usually released in the except or fianlly block and will not be used during subsequent program operation. Therefore, unless the resources are exhausted, these exceptions cannot affect the subsequent behavior of the program. When the resource exhaustion is resolved, you only need to purify the exceptions and record logs (for future improvement). In this case, there is no need to handle other errors.
2. If it is impossible to recover from an exception at a specific abstraction level, the code at that level does not need to handle the exception. Instead, the code at that level should throw an appropriate exception so that higher-level code can catch the exception and attempt to recover it. In this case, the most common implementation method is to omit the catch statement block and allow the exception to be broadcast.
##### Rule 2.3.2 When using try…except… to protect the code, use finally… to ensure that operation objects are released after an exception occurs.
**Rule 2.3.2 When using try…except… to protect the code, use finally… to ensure that operation objects are released after an exception occurs.**
When using try…except… to protect the code, if an exception occurs during code execution, use finally… to ensure that operation objects can be released.
[Compliant Code Example]
```python
handle = open(r"/tmp/sample_data.txt") # May raise IOError
try:
@@ -241,12 +254,13 @@ When using try…except… to protect the code, if an exception occurs during co
handle.close() # Always run after try:
```
##### Rule 2.3.3 Do not capture all exceptions by executing the "except:" statement.
**Rule 2.3.3 Do not capture all exceptions by executing the "except:" statement.**
Note that Python is tolerant of exceptions. The "except:" statement can capture any errors, including those in Python syntax. Executing the "except:" statement hides potential bugs. Therefore, specify exceptions to be handled when using try…except… to protect the code. The Exception class is the base class of most runtime exceptions and should not be used in the "except:" statement. The "try" statement should contain only exceptions that must be handled at the current location. The "except:" statement should only capture exceptions that must be handled. For example, for the code for opening files, the "try" statement should contain only the "open" statement. The "except:" statement only captures the FileNotFoundError exceptions. Other unexpected exceptions are captured by functions in the upper layer, or are transparently transmitted to external programs for exposure.
[Noncompliant Code Example]
Two types of exceptions may occur in the following code. When executing the "except:" statement for unified handle, if exceptions occur in the open statement execution, and the "except:" statement handle is invalid, the close method will be called and an error that the reported handle is undefined will be reported.
```python
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
@@ -254,7 +268,9 @@ Two types of exceptions may occur in the following code. When executing the "exc
except:
handle.close()
```
[Compliant Code Example]
```python
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
@@ -268,7 +284,7 @@ Two types of exceptions may occur in the following code. When executing the "exc
print(file_open_except)
```
##### Rule 2.3.4 The raise keyword that is not contained in the "except:" statement must have exceptions specified.
**Rule 2.3.4 The raise keyword that is not contained in the "except:" statement must have exceptions specified.**
**Note**: The raise keyword can be used only in the "try-except" statement and re-throw exceptions captured by the "except:" statement.
@@ -279,7 +295,9 @@ Two types of exceptions may occur in the following code. When executing the "exc
if a==1:
raise
```
[Compliant Code Example 1] Raise an exception or a custom exception.
```python
a = 1
if a==1:
@@ -287,6 +305,7 @@ Two types of exceptions may occur in the following code. When executing the "exc
```
[Compliant Code Example 2] Use the raise keyword in the "try-except" statement.
```python
try:
f = open('myfile.txt')
@@ -301,14 +320,14 @@ Two types of exceptions may occur in the following code. When executing the "exc
raise
```
#### <a name="psr">2.4 Serialization and Deserialization</a>
#### 2.4 Serialization and Deserialization
##### Rule 2.4.1 When pickle has security risks, do not use the pickle.load, cPickle.load, or shelve module to load untrusted data.
**Rule 2.4.1 When pickle has security risks, do not use the pickle.load, cPickle.load, or shelve module to load untrusted data.**
##### Rule 2.4.2 Use secure random numbers.
**Rule 2.4.2 Use secure random numbers.**
Python implements the random number generation function in the random module, and implements various distributed pseudo-random number generators. The generated random numbers can be
evenly distributed, in Gaussian distribution, logarithmic normal distribution, negative exponential distribution, alpha distribution, or beta distribution manners. However, these random numbers are pseudo-random numbers, and
evenly distributed, in Gaussian distribution, logarithmic normal distribution, negative exponential distribution, alpha distribution, or beta distribution manners. However, these random numbers are pseudo-random numbers, and
cannot be used for applications requiring security encryption.
Use /dev/random to generate secure random numbers, or use the secrets module introduced by Python 3.6 to generate secure random numbers.
@@ -334,7 +353,9 @@ Use /dev/random to generate secure random numbers, or use the secrets module int
print(sr)
```
##### Rule 2.4.3 The assert statement is usually used only in test code. Do not include the assert function in released versions.
**Rule 2.4.3 The assert statement is usually used only in test code. Do not include the assert function in released versions.**
The assert statement is used only for internal tests during R&D. If AssertionError occurs, it indicates that errors exist in software design or the code.
The software should be modified to resolve this issue. Do not include the assert function in externally released versions for production.
The software should be modified to resolve this issue. Do not include the assert function in externally released versions for production.
------------------------

+ 67
- 45
security/coding_guild_python_zh_cn.md View File

@@ -2,20 +2,19 @@

- [说明](#说明)
- [适用范围](#适用范围)
- [代码风格](#1-代码风格)
- [命名](#11-命名)
- [格式](#12-格式)
- [注释](#13-注释)
- [日志](#14-日志)
- [通用编码](#2-通用编码)
- [接口声明](#21-接口声明)
- [数据校验](#22-数据校验)
- [异常行为](#23-异常行为)
- [序列化和反序列化](#24-序列化和反序列化)
- [1. 代码风格](#1-代码风格)
- [1.1 命名](#11-命名)
- [1.2 格式](#12-格式)
- [1.3 注释](#13-注释)
- [1.4 日志](#14-日志)
- [2. 通用编码](#2-通用编码)
- [2.1 接口声明](#21-接口声明)
- [2.2 数据校验](#22-数据校验)
- [2.3 异常行为](#23-异常行为)
- [2.4 序列化和反序列化](#24-序列化和反序列化)

<!-- /TOC -->


## 说明

本规范以[PEP8](https://www.python.org/dev/peps/pep-0008/)为基础,参考华为Python通用编码规范、安全编程规范,并结合业界共识整理而成,参与MindSpore社区开发需要首先遵循本规范内容(与PEP8冲突部分),其余遵循PEP8规范;
@@ -27,47 +26,48 @@ MindSpore开源社区

------------------------


### 1. 代码风格

#### 1.1 命名

##### 规则 1.1.1 包名,模块名:小写,不使用下划线。
<font size=3>**规则 1.1.1 包名,模块名:小写,不使用下划线。**</font>

<font size=3>**规则 1.1.2 类名:使用驼峰格式,首字母大写,私有类下划线前缀。**</font>

##### 规则 1.1.2 类名:使用驼峰格式,首字母大写,私有类下划线前缀。
```python
class _Foo:
_instance = None
pass
```

##### 规则 1.1.3 函数名、变量名:小写,多个单词下划线分割。
<font size=3>**规则 1.1.3 函数名、变量名:小写,多个单词下划线分割。**</font>

```python
def _func_example(path):
pass
```

##### 建议 1.1.4 除迭代器与计数器除外,禁止使用单字符命名。
<font size=3>**建议 1.1.4 除迭代器与计数器除外,禁止使用单字符命名。**</font>

#### 1.2 格式

##### 规则 1.2.1 每行字符数不要超过 120 个。
<font size=3>**规则 1.2.1 每行字符数不要超过 120 个。**</font>

如果超过120个字符,请选择合理的方式进行换行。
如果超过120个字符,请选择合理的方式进行换行。

##### 规则 1.2.2 使用空格进行缩进,每次缩进4个空格,禁止tab缩进。
<font size=3>**规则 1.2.2 使用空格进行缩进,每次缩进4个空格,禁止tab缩进。**</font>

##### 规则 1.2.3 import顺序:标准库、第三方、自定义模块。
<font size=3>**规则 1.2.3 import顺序:标准库、第三方、自定义模块。**</font>

##### 规则 1.2.4 返回语句和条件语句中不使用括号。
<font size=3>**规则 1.2.4 返回语句和条件语句中不使用括号。**</font>

##### 规则 1.2.5 模块级函数和类之间双空行,类成员函数之间一空行,注释与代码间按需添加空行,原则上不超过两空行。
<font size=3>**规则 1.2.5 模块级函数和类之间双空行,类成员函数之间一空行,注释与代码间按需添加空行,原则上不超过两空行。**</font>

##### 规则 1.2.6 无效或冗余代码直接删除,不要以注释、TODO等方式保留在代码中,建议提issue记录。
<font size=3>**规则 1.2.6 无效或冗余代码直接删除,不要以注释、TODO等方式保留在代码中,建议提issue记录。**</font>

#### 1.3 注释

##### 规则 1.3.1 文件头注释必须包含版权声明
<font size=3>**规则 1.3.1 文件头注释必须包含版权声明。**</font>

所有python文件,均需包含如下版权声明:

@@ -98,52 +98,58 @@ import xxx
> 2020年新建的文件,应该是`Copyright 2020 Huawei Technologies Co., Ltd`
> 2019年创建年份,2020年修改年份,应该是`Copyright 2019-2020 Huawei Technologies Co., Ltd`

##### 规则 1.3.2 对外的类、方法、算子、Cell注释格式。
<font size=3>**规则 1.3.2 对外的类、方法、算子、Cell注释格式。**</font>

- `class` 和 `def` 的注释格式相同,采用业界通用的python注释语法,写在声明下方并缩进,所有的 `class` 和 `def` 都需要写注释,模块内部的类和方法可以只写一条简介。
- 注释格式详见[MindSpore注释规范](https://gitlab.huawei.com/mindspore/docs/wikis/Python-API%E6%B3%A8%E9%87%8A%E8%A7%84%E8%8C%83)。(注:资料的王婷后续会把这个wiki移到gitee)
- 注释格式详见[MindSpore注释规范](https://gitee.com/mindspore/community/blob/master/security/comments_specification.md)。

##### 规则 1.3.3 不允许通过注释屏蔽pylint告警。
<font size=3>**规则 1.3.3 不允许通过注释屏蔽pylint告警。**</font>

#### 1.4 日志

##### 规则 1.4.1 异常日志文本首字母大写。
<font size=3>**规则 1.4.1 异常日志文本首字母大写。**</font>

##### 规则 1.4.2 日志文本中变量名必须使用单引号注明。
<font size=3>**规则 1.4.2 日志文本中变量名必须使用单引号注明。**</font>

### 2. 通用编码

#### 2.1 接口声明

##### 规则 2.1.1 用户接口在文件的__all__中说明,__all__摆放在import与代码之间。
<font size=3>**规则 2.1.1 用户接口在文件的__all__中说明,__all__摆放在import与代码之间。**</font>

##### 规则 2.1.2 当前文件使用的非对外方法命名采用下划线前缀,内部跨模块使用的方法无需下划线前缀,用户接口在__all__中声明。
<font size=3>**规则 2.1.2 当前文件使用的非对外方法命名采用下划线前缀,内部跨模块使用的方法无需下划线前缀,用户接口在__all__中声明。**</font>

#### 2.2 数据校验

##### 规则 2.2.1 对所有外部数据进行合法性检查,包括但不限于:函数入参、外部输入命名行、文件格式,文件大小、环境变量、用户数据等。
<font size=3>**规则 2.2.1 对所有外部数据进行合法性检查,包括但不限于:函数入参、外部输入命名行、文件格式,文件大小、环境变量、用户数据等。**</font>

##### 建议 2.2.2 必须对文件路径进行规范化后再使用。
<font size=3>**建议 2.2.2 必须对文件路径进行规范化后再使用。**</font>

当文件路径来自外部数据时,需要先将文件路径规范化,如果没有作规范化处理,攻击者就有机会通过恶意构造文件路径进行文件的越权访问:
例如,攻击者可以构造“../../../etc/passwd”的方式进行任意文件访问。
在linux下,使用realpath函数,在windows下,使用PathCanonicalize函数进行文件路径的规范化。
【错误代码示例】
以下代码从外部获取到文件名称,拼接成文件路径后,直接对文件内容进行读取,导致攻击者可以读取到任意文件的内容:

```python
错误代码示例
```

【正确代码示例】
正确的做法是,对路径进行规范化后,再判断路径是否是本程序所认为的合法的路径:

```python
正确代码示例
```

【例外】
运行于控制台的命令行程序,通过控制台手工输入文件路径,可以作为本建议例外。

##### 规则 2.2.3 禁止调用OS命令解析器执行命令或运行程序。
<font size=3>**规则 2.2.3 禁止调用OS命令解析器执行命令或运行程序。**</font>

使用未经校验的不可信输入作为系统命令的参数或命令的一部分,可能导致命令注入漏洞。对于命令注入漏洞,命令将会以与Python应用程序相同的特权级别执行,它向攻击者提供了类似系统shell的功能。在Python中,os.system 或 os.popen 经常被用来调用一个新的进程,如果被执行的命令来自于外部输入,则可能会产生命令和参数注入。
执行命令的时候,请注意以下几点:

1. 命令执行的字符串不要去拼接输入的参数,如果必须拼接时,要对输入参数进行白名单过滤。
2. 对传入的参数要做类型校验,例如:整数数据,可以对数据进行整数强制转换。
3. 保证格式化字符串的正确性,例如:int类型参数的拼接,对于参数要用%d,不能用%s。
@@ -181,11 +187,15 @@ c:\\dbms\\*.* ":
except Exception as ex:
print('exception:', ex)
```

攻击者可以通过以下命令来利用这个漏洞程序:

```python
python test.py ". && echo bad"
```

实际将会执行两个命令:

```python
ls .
echo bad
@@ -193,6 +203,7 @@ c:\\dbms\\*.* ":

【正确代码示例】
避免使用 os.system,可以使用标准的 API 替代运行系统命令来完成任务:

```python
import os
import sys
@@ -204,11 +215,12 @@ c:\\dbms\\*.* ":

#### 2.3 异常行为

##### 规则 2.3.1 异常必须被妥当处理,禁止抑制或者忽略已检查异常。
<font size=3>**规则 2.3.1 异常必须被妥当处理,禁止抑制或者忽略已检查异常。**</font>

每一个except 块都应该确保程序只会在继续有效的情况下才会继续运行下去。except 块必须要么从异常情况中恢复,要么重新抛出适合当前catch块上下文的另一个异常以允许最邻近的外层try-except 语句块来进行恢复工作。
【正确代码示例】
正确的做法是,避免使用 os.system,可以使用标准的 API 替代运行系统命令来完成任务:

```python
validFlag = False
while not validFlag:
@@ -220,14 +232,18 @@ c:\\dbms\\*.* ":
import traceback
traceback.print_exc()
```
【例外情况】:

【例外情况】:

1. 在资源释放失败不会影响程序后续行为的情况下,释放资源时发生的异常可以被抑制。释放资源的例子包括关闭文件、网络套接字、线程等等。这些资源通常是在except或者fianlly块中被释放,并且在后续的程序运行中都不会再被使用。因此,除非资源被耗尽,否则不会有其他途径使得这些异常会影响程序后续的行为。在充分处理了资源耗尽问题的情况下,只需对异常进行净化和记录日志(以备日后改进)就足够了;在这种情况下没必要做其他额外的错误处理。
2. 如果在特定的抽象层次上不可能从异常情况中恢复过来,则在那个层级的代码就不用处理这个异常,而是应该抛出一个合适的异常,让更高层次的代码去捕获处理,并尝试恢复。对于这种情况,最通常的实现方法是省略掉catch语句块,允许异常被广播出去。

##### 规则 2.3.2 使用try…except…结构对代码作保护时,需要在异常后使用finally…结构保证操作对象的释放。
<font size=3>**规则 2.3.2 使用try…except…结构对代码作保护时,需要在异常后使用finally…结构保证操作对象的释放。**</font>

使用try…except…结构对代码作保护时,如果代码执行出现了异常,为了能够可靠地关闭操作对象,需要使用finally…结构确保释放操作对象。

【正确代码示例】

```python
handle = open(r"/tmp/sample_data.txt") # May raise IOError
try:
@@ -238,11 +254,13 @@ c:\\dbms\\*.* ":
handle.close() # Always run after try:
```

##### 规则 2.3.3 不要使用“except:”语句来捕获所有异常。
<font size=3>**规则 2.3.3 不要使用“except:”语句来捕获所有异常。**</font>

在异常这方面, Python非常宽容,“except:”语句真的会捕获包括Python语法错误在内的任何错误。使用“except:”很容易隐藏真正的bug,我们在使用try…except…结构对代码作保护时,应该明确期望处理的异常。Exception类是大多数运行时异常的基类,一般也应当避免在except语句中使用。通常,try只应当包含必须要在当前位置处理异常的语句,except只捕获必须处理的异常。比如对于打开文件的代码,try应当只包含open语句,except只捕获FileNotFoundError异常。对于其他预料外的异常,则让上层函数捕获,或者透传到程序外部来充分暴露问题。

【错误代码示例】
如下代码可能抛出两种异常,使用“except:”语句进行统一处理时,如果是open执行异常,将在“except:”语句之后handle无效的情况下调用close,报错handle未定义。

```python
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
@@ -250,7 +268,9 @@ c:\\dbms\\*.* ":
except:
handle.close()
```

【正确代码示例】

```python
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
@@ -264,9 +284,9 @@ c:\\dbms\\*.* ":
print(file_open_except)
```

##### 规则 2.3.4 不在except分支里面的raise都必须带异常。
raise关键字单独使用只能出现在try-except语句中,重新抛出except抓住的异常。
<font size=3>**规则 2.3.4 不在except分支里面的raise都必须带异常。**</font>

raise关键字单独使用只能出现在try-except语句中,重新抛出except抓住的异常。

【错误代码示例】

@@ -275,7 +295,9 @@ raise关键字单独使用只能出现在try-except语句中,重新抛出excep
if a==1:
raise
```

【正确代码示例1】raise一个Exception或自定义的Exception

```python
a = 1
if a==1:
@@ -283,6 +305,7 @@ raise关键字单独使用只能出现在try-except语句中,重新抛出excep
```

【正确代码示例2】在try-except语句中使用

```python
try:
f = open('myfile.txt')
@@ -299,10 +322,9 @@ raise关键字单独使用只能出现在try-except语句中,重新抛出excep

#### 2.4 序列化和反序列化

##### 规则 2.4.1 pickle存在安全性问题,禁止使用pickle.load、cPickle.load和shelve模块加载不可信数据。

<font size=3>**规则 2.4.1 pickle存在安全性问题,禁止使用pickle.load、cPickle.load和shelve模块加载不可信数据。**

##### 规则 2.4.2 使用安全随机数。
<font size=3>**规则 2.4.2 使用安全随机数。**</font>

Python产生随机数的功能在random模块中实现,实现了各种分布的伪随机数生成器。产生的随机数可
以是均匀分布,高斯分布,对数正态分布,负指数分布以及alpha,beta分布,但是这些随机数都是伪随机数,不
@@ -331,9 +353,9 @@ Python产生随机数的功能在random模块中实现,实现了各种分布
print(sr)
```

##### 规则 2.4.3 assert语句通常只在测试代码中使用,禁止在Release版本中包含assert功能。
<font size=3>**规则 2.4.3 assert语句通常只在测试代码中使用,禁止在Release版本中包含assert功能。**</font>

assert只应在研发过程中内部测试时使用,出现了AssertionError异常说明存在软件设计或者编码上的错误,应
当修改软件予以解决。在对外发布的生产版本中禁止包含assert功能。

------------------------
------------------------

Loading…
Cancel
Save