The Python Tutorial 3.2-4 More Control Flow Tools(深入控制流)

UE4 C++开发环境搭建:基于Rider的完整避坑指南与调试实战 C++作为游戏引擎开发的核心语言,其开发环境的搭建是项目启动的关键基础。其原理在于配置编译器、构建工具和调试器之间的协同工作链,确保代码能够被正确编译、链接和执行。对于使用Unreal Engine(UE)进行C++开发的工程师而言,一个稳定高效的开发环境能极大提升代码编写、问题排查和迭代的效率。在实际应用场景中,开发者常需处理引擎源码编译、IDE智能感知配置和断点调试等核心环节。本文聚焦于使用JetBrains Rider这一深度集成Unreal Engine的IDE,详细解析从获取引擎源码、编译、到配置 阅读详情

4. More Control Flow Tools(深入控制流)


Besides the while statement just introduced, Python knows the usual control flow statements known from other languages, with some twists.

除了上一节介绍的 while 循环语句外,Python像其他语言一样支持常用的流程控制语句,当然也有一些自己的元素。

4.1. if Statements(if语句)

Perhaps the most well-known statement type is the if statement. For example:

if 语句也许是最有名的语句类型。例如:

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print('Negative changed to zero')
... elif x == 0:
...      print('Zero')
... elif x == 1:
...      print('Single')
... else:
...      print('More')
...
More

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. An if ... elif ... elif ... sequence is a substitute for the switch or case statements found in other languages.

if 语句可以有零个或多个 elif 分支语句,并且 else 分支语句是可选的。 elif 关键字是’else if’的缩写,这可以有效避免过度缩进问题。在Python中,使用 if ... elif ... elif 语句组合代替像其他语言中的 switch 和 case 语句。

4.2. for Statements(for语句)

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):

for语句可能与你在C或Pascal语言中用过的有些不同。与总是依靠一个等差数字进行迭代(类似Pascal)或者赋予用户定义迭代步进和终止条件的能力(类似C)不同,Python的 for 语句是对任何序列(列表或字符串)的项按照它们在序列中的顺序进行迭代。例如:

>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
...     print(x, len(x))
...
cat 3
window 6
defenestrate 12

It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:

在循环中修改正在被迭代的序列是不安全的(这仅在可变序列类型上发生,像列表)。如果需要修改正在迭代的列表(比如复制选择的项),你必须对它的副本进行迭代。切片操作可以方便的做到这一点。

>>> for x in a[:]: # make a slice copy of the entire list
...    if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

4.3. The range() Function(range()函数)

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions:

如果你必须迭代一个数字序列,内置函数 range() 会派上用场。它生成一个等差级数序列

>>> for i in range(5):
...     print(i)
...
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的序列的合法索引。可以让 range 函数从另一个数值开始,或者指定一个不同的增量(甚至是负数,有时它被称为“步长”)。

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

To iterate over the indices of a sequence, you can combine range() and len() as follows:

为了迭代序列的索引,你可以结合使用 range() 和 len() (实现)。如下所示:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

In most such cases, however, it is convenient to use the enumerate() function, see Looping Techniques.

然而在大多数此类情况下,使用 enumerate() 函数更方便。参考 Looping Techniques 遍历技巧 。

A strange thing happens if you just print a range:

如果你只是打印一个 range (方法调用)会发生奇怪的事情。

>>> print(range(10))
range(0, 10)

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() 函数是另外一个(迭代器),它从可迭代(对象)中创建列表。
>>> list(range(5))
[0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take iterables as argument.

稍后我们会看到更多返回可迭代(对象)和以可迭代(对象)作为参数的函数

4.4. break and continue Statements, and else Clauses on Loops(循环中的break,continue语句,else子句)

The break statement, like in C, breaks out of the smallest enclosing for or while loop.

像在C语言中一样, break 语句用于跳出最近的 for 循环或 while 循环。

The continue statement, also borrowed from C, continues with the next iteration of the loop.

continue 语句,同样借鉴自C语言,继续循环的下一次迭代过程。

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

循环语句可以包含一个 else 子句,当循环因穷尽列表项( for 循环)或循环条件变为false( while 循环)而终止时执行它,而通过 break 语句结束循环时并不执行。下面这个搜索素数的循环是一个间的示例:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

这是正确的代码。仔细看,else子句附属于for循环而不是if语句

4.5. pass Statements(pass语句)

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

pass 语句不做任何事。它被用于语法结构上需要一条语句但并不做任何事时。例如:

>>> while True:
...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
...

This is commonly used for creating minimal classes:

这通常被用在创建最小类上。

>>> class MyEmptyClass:
...     pass
...

Another place pass can be used is 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. The pass is silently ignored:

另外一个可以用 pass 的地方是当你新编写一个函数结构或条件体代码时,这使你在更抽象的层面思考。 pass 被默默的忽略。

>>> def initlog(*args):
...     pass   # Remember to implement this!
...

4.6. Defining Functions(函数定义)

We can create a function that writes the Fibonacci series to an arbitrary boundary:

我们可以创建一个输出指定边界的斐波那契数列的函数

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.

关键字 def 声明一个函数 定义 。其后必须跟着函数名和以括号标明的参数列表。必须在下一行开始构成函数体的语句,并且必须缩进。

The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or docstring. (More about docstrings can be found in the section Documentation Strings.) There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it’s good practice to include docstrings in code that you write, so make a habit of it.

函数体的第一行语句可以是可选的字符串常量,这个字符串是函数的文档字符串,或者称为 docstring 。(更多关于 docstrings 的信息请参考 Documentation Strings 文档字符串 。)有些工具通过 docstrings 自动生成在线的或可打印的文档,或者让用户通过代码交互浏览;在你的代码中包含 docstrings 是一个好的实践,让它成为习惯吧。

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

函数调用会为函数局部变量生成一个新的符号表。确切的说,所有函数中的变量赋值都是将值存储在局部符号表。变量引用首先在局部符号表中查找,然后是包含函数的局部符号表,然后是全局符号表,最后是内置名字表。因此,全局变量不能在函数中直接赋值(除非用 global 语句命名),尽管他们可以被引用。

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). [1] When a function calls another function, a new local symbol table is created for that call.

当函数调用时,实参被引入调用函数的局部符号表;因此,参数是通过 传值 方式传递的(这里 值 总是指代对象的 引用 ,而非对象的值)。 [1] 当一个函数调用其他函数时,将为此调用创建一个新的字符表。

A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:

一个函数定义会在当前符号表内引入函数名。函数名指代的值(即函数体)有一个被Python解释器认定为 用户自定义函数 的类型。这个值可以赋予其他的名字(即变量名),然后它也可以被当做函数使用。这可以作为通用的重命名机制:

>>> fib

>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a return statement do return a value, albeit a rather boring one. This value is called None (it’s a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using print():

如果你使用过其他语言,你可能会反对说: fib 不是一个函数,而是一个procedure(过程),因为它并不返回任何值。事实上,没有 return 语句的函数确实会返回一个值,虽然是一个相当令人厌烦的值(指 None )。这个值被称为 None (这是一个内建名称)。如果 None 值是唯一被书写的值,那么在写的时候通常会被解释器忽略(即不输出任何内容)。如果你确实想看到这个值的输出内容,请使用 print() 函数。

>>> fib(0)
>>> print(fib(0))
None

It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:

定义一个返回斐波那契数列数字列表的函数,而不是打印它,是很简单的:

>>> def fib2(n): # return Fibonacci series up to n
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a)    # see below
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100)    # call it
>>> f100                # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

This example, as usual, demonstrates some new Python features:

照例,这个列子包含了一些Python的新特性:

The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.

return 语句从函数中返回一个值(可以是多个)。没有表达式参数的 return 语句返回 None 值。函数执行最后(指没有 return 语句的情况)也会返回 None 值。

The statement result.append(a) calls a method of the list object result. A method is a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, see Classes) The method append() shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to result = result + [a], but more efficient.

result.append(b) 语句调用了列表对象 result 的一个 方法 。方法是属于对象的函数,并被命名为 obj.methodname ,此处 obj 是某个对象(也可能是个表达式), methodname 是对象类型定义的方法的名字。不同的(对象)类型定义了不同的方法。不同(对象)类型的方法可能拥有相同的名字,但这并不会导致胡乱。(你可以使用 clasees 对应自己的对象类型和方法,参考 Classes 类 )示例中出现的 append() 方法是由列表对象定义的,它将一个新元素添加到列表的末尾。在这个示例中它等同于 result = result + [b] (表达式运算),但是更高效。

4.7. More on Defining Functions(深入函数定义)

It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.

在Python中,你也可以定义包含若干参数的函数。这里有三种可用的形式,也可以混合使用

4.7.1. Default Argument Values(默认参数值)

The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:

最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义时允许的参数更少的参数调用的函数:

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print(complaint)

This function can be called in several ways:

这个函数可以通过几种方式调用:

  • giving only the mandatory argument: ask_ok('Do you really want to quit?')
  • 仅给出必须得参数:ask_ok('Do you really want to quit?')
  • giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
  • 给出一个可选的参数:ask_ok('OK to overwrite the file?', 2)
  • or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
  • 或者给出所有的参数:ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value.

本示例同样介绍了 in 关键字。它检测序列中是否包含某个指定的值。

The default values are evaluated at the point of function definition in the defining scope, so that

默认值在定义范围内函数定义时求值,例如:

i = 5

def f(arg=i):
    print(arg)

i = 6
f()

will print 5.

将会打印5

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

强烈警告: 默认值只被求值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数。

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

This will print

它将会打印

[1]
[1, 2]
[1, 2, 3]

If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

如果你不想让默认值在后续调用中累积,你可以像下面一样定义函数。

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
4.7.2. Keyword Arguments(关键字参数)

Functions can also be called using keyword arguments of the form keyword = value. For instance, the following function:

函数同样可以使用 keyword = value 形式的键字参数来调用。例如,下面的函数:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

could be called in any of the following ways:

可以使用如下任何方式来调用上面函数:

parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

but the following calls would all be invalid:

但是下面的一些调用将是无效的:

parrot()                     # required argument missing(缺少必要的参数)
parrot(voltage=5.0, 'dead')  # non-keyword argument following keyword(在关键字后存在非关键字参数)
parrot(110, voltage=220)     # duplicate value for argument(对同一参数多重赋值)
parrot(actor='John Cleese')  # unknown keyword(未知的关键字参数)

In general, an argument list must have any positional arguments followed by any keyword arguments, where the keywords must be chosen from the formal parameter names. It’s not important whether a formal parameter has a default value or not. No argument may receive a value more than once — formal parameter names corresponding to positional arguments cannot be used as keywords in the same calls. Here’s an example that fails due to this restriction:

通常,参数列表必须(先书写)位置参数然后才是关键字参数,这里关键字必须来自于形参名字。形参是否有一个默认值并不重要。任何参数都不能被多次赋值——在同一个调用中,与位置参数相同的形参名字不能用作关键字。这里有一个违反此限制而出错的例子:

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form **name is present, it receives a dictionary (see Mapping Types — dict) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) 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 形式时,函数接受一个包含所有未出现在形参列表中的关键字参数的字典(参考 Mapping Types — dict )。这可以结合形式为 *name 的形参(在下一节中介绍)一起使用,它接受一个包含所有未出现在形参列表中的位置参数的元组( *name 必须出现在 **name 之前)。例如,我们定义如下函数:

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    keys = sorted(keywords.keys())
    for kw in keys:
        print(kw, ":", keywords[kw])

It could be called like this:

它可能被这样调用:

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

and of course it would print:

它将输出:

 
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

Note that the list of keyword argument names is created by sorting the result of the keywords dictionary’s keys() method before printing its contents; if this is not done, the order in which the arguments are printed is undefined.

注意:关键字参数名的列表内容在打印前需要对关键字字典的 keys() 方法返回的值排序(即在输出列表前需要对列表的键排序),否则参数输出的循序是未知的。

4.7.3. Arbitrary Argument Lists(可变参数列表)

Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see Tuples and Sequences). Before the variable number of arguments, zero or more normal arguments may occur.

最后,指明一个函数可以使用任意数目的参数调用是极少的选择。这些参数将被包装进一个元组(参考 Tuples and Sequences 元组和序列 )。在可变数目的参数前,可以有零或多个普通的参数。

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

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)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
4.7.4. Unpacking Argument Lists(拆分参数列表)

The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:

一种相反的情况是:当参数是一个列表或元组但函数需要分开的位置参数时,就需要拆分参数。比如,内建函数 range() 期望独立的 start 和 stop 参数。如果他们不是独立的有效(参数),调用函数时使用 *- 操作符将参数从列表或元组中拆分出来即可。

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]

In the same fashion, dictionaries can deliver keyword arguments with the **-operator:

以此类推,字典可以使用 **- 操作符拆分成关键字参数。

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
4.7.5. Lambda Forms(Lambda表达式)

By popular demand, a few features commonly found in functional programming languages like Lisp have been added to Python. With the lambda keyword, small anonymous functions can be created. Here’s a function that returns the sum of its two arguments: lambda a, b: a+b. Lambda forms can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda forms can reference variables from the containing scope:

出于普遍需求,一些通常在函数式编程语言中出现的特性被加入到Python中,如Lisp。使用 lambda 关键字,可以创建短小的匿名函数。这里有一个返回两个参数之和的(Lambda)函数: lambda a, b: a+b 。 Lambda方式可是使用在任何需要函数对象的地方。出于语法的限制,他们只能是一个独立的表达式。从语义上讲,它们只是普通函数定义的语法糖。类似于嵌套函数定义,lambda方式可以从包含域内引用变量。

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
4.7.6. Documentation Strings(文档字符串)

Here are some conventions about the content and formatting of documentation strings.

这里是一些关于文档字符串内容和格式的约定。

The first line should always be a short, concise summary of the object’s purpose. For brevity, it should not explicitly state the object’s name or type, since these are available by other means (except if the name happens to be a verb describing a function’s operation). This line should begin with a capital letter and end with a period.

第一行应该总是关于对象用途的摘要。为了简便起见,无需明确说明对象的名称或类型,因为这些都可以通过其他方法获取(除非名字碰巧是描述一个函数操作的动词)。这一行应该以大写字母开头,并且以句号结束。

If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object’s calling conventions, its side effects, etc.

如果文档字符串包含多行,第二行应该是空行,在视觉上将摘要(指第一行)与区域的描述内容分割。接下来应该是一段或多段(内容),用来描述对象调用约定和边界效应等。

The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can’t use the first line since it is generally adjacent to the string’s opening quotes so its indentation is not apparent in the string literal.) Whitespace “equivalent” to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).

在Python中,语法分析器不会从多行字符串中去除缩进,因此如果需要处理文档的工具必须自己去除缩进。这是通过以下的约定实现的:第一行 之后 的第一个非空行决定了整个文档字符串缩进的值。(我们不用第一行是因为它通常紧接在字符串起始引号,以致它在字符串中的缩进并不明显。)字符串中所有行开始的“相当于”缩进的空白都会被去除掉。不应出现缩进不足的行(指有的行缩进空格数少于整体),如果出现此情况所有的前导空白都应该被去除。在扩展制表符后需要对相等的空白做测试(通常为8个空格)。

Here is an example of a multi-line docstring:

这里是一个多行docstring的示例:

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

4.8. Intermezzo: Coding Style(编码风格)

Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about coding style. Most languages can be written (or more concise, formatted) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that.

现在你可以编写更长更复杂的python代码块,现在是该谈论代码风格了。许多语言可以使用多种风格编写(或者更简洁、格式化);有些比其它更具有可读性。将你的代码更容易阅读是一个好主意,采取良好的代码风格极大有助于这些.

For Python, PEP 8 has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; here are the most important points extracted for you:对于Python而言, PEP 8 已经成为大多数项目使用的风格,它提供了一个非常可读的并且诱人的编码风格。每一位Python开发者都应该找个时间读一下它,这里是为你概括的最重要的几点:

Use 4-space indentation, and no tabs.

使用4个空格的缩进,并杜绝制表符。

4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, and are best left out.

4个空格是一个介于小缩进(允许更深层的嵌套)和大缩进(更利于阅读)好的折中(选择)。制表符会导致混乱(因为不同编辑器上的制表符表示的空格可能不同),最好将它遗忘。

Wrap lines so that they don’t exceed 79 characters.

换行,避免他们超过79个字符。

This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.

这可以帮助使用小显示器的用户,并且使得在大显示器上并排显示几个代码文件成为可能。

Use blank lines to separate functions and classes, and larger blocks of code inside functions.

使用空行分割类和函数以及函数内部较大的代码块。

When possible, put comments on a line of their own.

如果可以,将注释独立成行。

Use docstrings.

使用文档字符串

Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).

在操作符两侧和逗号之后使用空格,但不要直接在括号内部使用: a = f(1, 2) + g(3, 4) 。

Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classes for more on classes and methods).

使用统一风格命名你的类和函数:约定使用 CamelCase 方式命名类,使用 lower_case_with_underscores 方式命名函数和方法。总是用 self 作为方法的第一个参数名(参考 A First Look at Classes 初识类 深入类和方法)。

Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.

如果你希望你的代码被用在国际环境中,不要使用新奇的编码。 Python默认的UTF-8编码甚至ASCII编码在任何情况下都将工作的更好

Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.

同样的,如果仅有极少数说其他语言的人将要阅读或维护代码,不要使用非ASCII字符的标识符

Footnotes(脚注)

[1] Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).

事实上, 对象引用调用 可能是个更好的表述,因为如果传递一个可变对象(参数),调用者将会观察到被调用者对其所做的任何改变(向列表插入元素)。

【信息科学与工程学】【数据中心】第三十五篇 云计算数据中心的学科知识04 编号学科(课程)核心知识点在云计算/云存储/云网络/云安全/云MaaS中的作用代表教材/资料/论文 + 数学方程式列表工业界应用D1421​云原生数据库:TiDB​HTAP(混合事务/分析处理)、分布式SQL、水平扩展、强一致(Raft)、自动故障恢复、与MySQL兼容、TiFlash列式引擎提供弹性扩展的分布式数据库;支撑高并发在线交易与实时分析教材:《TiDB in Action》PingCAP(2020) 论文:《TiDB: A Raft-based HTAP Database》(2017) 阅读详情

相关推荐

Shell_经典实例

Shell_经典实例,UNIX/Linux最重要的软件之一就是shell,目前最流行的shell被称为Bash(Bourne Again Shell),几乎所有的Linux和绝大部分的UNIX都可以使用Bash。作为系统与用户之间的交互接口,shell几乎是你在UNIX工作平台上最亲密的朋友。

python-control系统库从入门到精通

python-control是一款Python库,实现了反馈控制系统的分析与设计过程中的基本操作。控制分析:稳定性、可达性、可观性,稳定性裕量。控制设计:特征值配置、LQR、H2、Hinf。模型缩小:平衡的实现,Hankel奇异值。非线性输入与输出系统建模、仿真与分析。估计设计:线性二次估计(卡尔曼滤波)状态空间与频域的线性输入与输出系统。块框图代数:串型、并行和反馈互联。时域响应:初始化、阶跃、脉冲响应。频域响应:伯德图、奈奎斯特图。

价值知识传播者 2631

完整的Flex中文帮助文档 PDF格式

完整的Flex中文帮助文档 pdf 格式 想学flex的朋友进

Python Control Systems Library 使用教程

Python Control Systems Library 是一个用于分析和设计反馈控制系统的 Python 模块。该库提供了基本的操作,包括线性输入/输出系统的状态空间和频域表示、非线性输入/输出系统的建模、仿真和分析,以及块图代数(串行、并行和反馈连接)等功能。 ## 项目快速启动 ### 安装 首先,你需要安装 Python Control Systems Library。你可以使用...

gitblog_00123的博客 1263

Cobalt Strike4.0安装包(内附中文版)

1.什么是 Cobalt Strike Cobalt Strike 是一个为对手模拟和红队行动而设计的平台,主要用于执行有目标的攻击和模拟高级威胁 者的后渗透行动。 Cobalt Strike已经不再使用MSF而是作为单独的平台使用,它分为客户端与服务端,服务端是一个,客户端可以有多个,可被团队进行分布式协团操作。集成了端口转发、扫描多模式端口Listener、Windows exe程序生成、W...

梦之序章的博客 2万+

C#与西门子PLC通讯——新手快速入门

本文基于C# .Net Core和西门子博图TIA Portal V17搭建。由于手边没有西门子PLC实物,所以采用S7-PLCSIM Advanced V4.0作为模拟PLC,以实现0成本完成通讯测试实例。这篇入门笔记解决了新手第一次上手实践时遇到的坑,并且有意忽略了实际项目中会遇到的逻辑交互和更多的数据格式问题。

吾家有猫名探花的博客 2万+

Python notes 0006: Control Flow Tools 1

Contents1 Basic knowledge1.2 Concept22.12.2 More Control Flow Tools2.2.1 `if` Statements2.2.2 `break` and `continue` Statements, and `else` Clauses on Loops 1 Basic knowledge 1.2 Concept 2 2.1 ①Open cmd.exe and enter python to enter interactive mode. ②we c

weixin_44123746的博客 311

STM32F4XX软件模拟I2C实现MPU6050姿态数据采集

本文详细介绍了在STM32F4XX平台上通过软件模拟I2C驱动MPU6050传感器实现姿态数据采集的完整方案。内容涵盖软件I2C的GPIO配置、核心通信函数实现、MPU6050寄存器配置详解以及数据读取处理流程,为硬件资源受限的嵌入式应用提供了灵活的解决方案,并分享了调试技巧与常见问题处理方法。

butter的博客 678

【python 报错】ValueError: variadic keyword parameters cannot have default values

【python报错】:ValueError: variadic keyword parameters cannot have default values

weixin_38692258的博客 587

交流电路计算方法:复阻抗和相量法

一,复阻抗 电容电路,电压与电流的大小比值是XC=1/WC,相位上电流比电压超前90度 这样描述很麻烦,在复平面里,相位超前90度,可以用什么数学表示呢? 也就是说,一个相量,乘以j之后,大小没变化,相位变得超前90度了 同样的,大小不变,相位落后90度应该除以j 原来我们说电容电路,给个电压,算电流又要算XC,又要另外说相位超前90度,现在可以简单点 在这个计算式里,1/wc还是原来的容抗大...

theory and practice的博客 3万+

Windows下ArduPilot SITL仿真环境搭建与QGC地面站联调全攻略

软件在环仿真(SITL)是无人机开发中的关键一环,它通过将飞控固件运行在PC上,用数学模型模拟传感器数据,实现无硬件依赖的飞行逻辑验证。这项技术不仅降低了试错成本,更为地面站开发、自动化测试和任务规划提供了安全可控的试验场。在工程实践中,MAVLink协议作为飞控与地面站之间的通信桥梁,贯穿仿真、遥测与指令控制全程。结合QGroundControl(QGC)这一主流地面站,开发者可以直观地观察飞行状态、规划航点并记录日志。本文以Windows原生环境为例,详细介绍ArduPilot SITL的搭建流程、MA

weixin_31858171的博客 317

swift学习笔记5 函数

注:英文部分来自官方文档 Every function in Swift has a type, consisting of the function’s parameter types and return type. You can use this type like any other type in Swift, which makes it easy to pass function

peterchen149的博客 630

Python爬虫实战:模拟登录知乎 – 通过加密参数和验证码实现自动登录

通过本篇博客的讲解,我们学习了如何通过 POST请求 和 验证码识别,模拟登录知乎并爬取用户信息、问题数据。随着爬虫技术的发展,面对更复杂的反爬虫机制,我们可以不断调整策略,以绕过这些防护,实现数据的自动化抓取。

2201_76125261的博客 731

The Python Tutorial 4——More Control Flow Tools

4. More Control Flow Tools 4.1. if Statements >>> x = int(raw_input("Please enter an integer: ")) Please enter an integer: 42 >>> if x < 0: ... x = 0 ... print 'Negative changed to zero'

yangcs2009的专栏 909

通过情感分类实例 详细介绍如果借助Huggingface平台 完成Transformers模型运行(包括配置环境-tokenizer-Model-输出头-预测)

attention_mask和padding是配套使用的,当人为去修改padding的时候,也要把attention_mask里面的参数进行修改。下载Huggingface包,Huggingface可以说是一个社区,集成了很多nlp的模型、数据集、预训练权重文件等等,并且免费,只需要pip install下载即可。那么用什么做分类就选择什么输出头,就import什么东西。代码中使用了自动分词器选择,它是由checkpoint指定的预训练模型关联的,不用我们自己选择tokenizer,它自动帮我们选择好了。

LZL2020LZL的博客 1136

Java语音革命:用代码打造永不疲倦的AI客服,让客户支持效率飙升300%!

客户支持领域常面临“薛定谔困境”,即无法预知客户来电的意图是投诉还是表扬。通过Java技术,尤其是语音识别和自然语言处理(NLP),可以有效解决这一问题。文章展示了如何利用Java代码构建“声纹量子引擎”,实现客户支持的自动化。核心技术包括录音与预处理、语音识别和语义理解。通过百度AI API和Stanford NLP,系统能够快速、准确地识别客户语音并理解其意图。数据表明,优化后的AI处理时间从15分钟缩短至18秒,语音识别准确率提升至98.5%,并发处理能力达到单实例1000+请求。这些技术显著提升了客

墨夶的博客 1035

Python Tutorial中英双语对照文档1

适合python初学者的; Python Tutorial中英双语对照文档

huwhois的博客 1535

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【Programming】

增强式学习,借助定义 Actions、States、Rewards 的方式不断训练机器循序渐进,学会执行某项任务的算法。常用算法有Q-LearningTDSarsa总结的比较好的一个机器学习框架TensorFlow:低级深度学习链接库,Brain Team 开发,15年11月公开源码Keras:高级深度学习链接库1)Tensor(张量)零维的 Tensor 是标量,1维的是向量,2维以上的是矩阵2)Flow(数据流)去陌生的城市,不会当地的语言,最好的方式,画一张图告诉司机你的目的地Node。

bryant_meng 3519

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Harness AI工程化编程实战:从AI Agent原理到Hermes框架生产部署

AI Agent作为能够感知环境、自主决策并执行动作的智能系统,其核心原理在于超越传统对话式AI的目标导向性和工具使用能力。通过模块化架构和自进化机制,AI Agent实现了从简单问答到复杂任务处理的跨越,在自动化业务流程、技术文档分析等场景展现巨大技术价值。Harness Engineering作为新一代AI工程化方法论,通过Prompt设计规范化、上下文工程和控制流工程三大支柱,解决了AI系统在实际业务场景中的稳定性问题。以Hermes Agent为代表的开源框架,集成了自进化能力和生产就绪特性,为开发

weixin_30458043的博客 404

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

mysql中ERROR 1364 (HY000): Field 'xxxx' doesn't have a default value的解决方案

先上个图,这个是我的user表 然后当我输入了insert into user(password) values(‘xxxxxx’);之后发现这如下报错 大概中文意思就是email没有默认值 那是因为插入数据的时候只插入了一个password 简而言之,就是说插入的时候需要一次性把所有没有默认值的字段都要插入 即: 然后就能通过select看到 ...

weixin_45126025的博客 1万+

Field ‘userID‘ doesn‘t have a default value

Caused by: java.sql.SQLException: Field 'userID' doesn't have a default value 字段需要设置一个默认值

niaonao 8万+

bugfree升级报错“Field 'id' doesn't have a default value”问题解决

MySQL 5中,出现错误提示: Field 'id' doesn't have a default value 解决方法: 打开my.ini,查找 sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 修改为 sql-mode="NO_AUTO_CREATE_USER,NO_

云天空的博客 633

HQL中设置参数出现 cannot define positional parameter after any named parameters have been defined

在HQL中可以使用?或者:***的方式在外部配置查询参数,但我们决不能在HQL中又出现?,又出现变量占位符,即Query query=session.createQuery("from TestStu s where s.team=? and s.age>:age);这样,在设置

cztjing的专栏 3104

django数据库错误相关问题

http://blog.csdn.net/pipisorry/article/details/45727309 django数据库错误相关问题 问题:字段修改属性发生错误 >python manage.py makemigrations You are trying to add a non-nullable field 'price_monthly' to product wi

皮皮blog 7万+

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 413

从一段视频到可漫游的 4D 有声场景:思路拆解与最小复现手记

只需一段手机视频,你就能生成可"走进去"的 4D 有声场景:转头时狗叫声方向随之变化,走近时声音更清晰。本文拆解 Video-to-4DAVScene 的核心思路,手把手带你用几十行 Python 搭出最小管线,把视频中的运动物体变成带空间位置的声源,并附上三个真实踩坑的排障经验,代码可直接跑。🎧

helloagent的博客 235
上一篇: The Python Tutorial 3.2 - 8Errors and Exceptions(错误和异常)
下一篇: 更改java web项目编码的过程记录
Lbeta
博客等级 码龄15年 4粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值