python流程控制

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

for

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
... 
cat 3
window 6
defenestrate 12
>>> 

for user, status in users.copy().items(): #使用副本去删除某个item
...     if status == 'inactive':
...             del users[user]
>>> activeusers = {}
>>> for user, status in users.items():
...     if status == 'active':
...             active_users[user] = status
... 

range()

>>> for i in range(5): #作闭右开
...     print(i)
... 
0
1
2
3
4
>>> 

>>> range(5, 10)
5, 6, 7, 8, 9
>>> 
>>> range(0, 10, 3) # 等差数列 3是step
0, 3, 6, 9
>>> range(-10, -100, -30) # 等差数列 -30是step
-10, -40, -70
>>> 

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)): # len()获取数组长度
...     print(i, a[i]) # 输出索引和对应的值
... 
0 Mary
1 had
2 a
3 little
4 lamb
>>> 

# enumerate
>>> seasons = ['Spring', "Summer", "Fall", "winter"]
>>> list(enumerate(seasons)) 
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'winter')]
>>> list(enumerate(seasons, start=1)) # 索引从1开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'winter')]
>>> 
>>> print(range(10))
range(0, 10) # range() 返回的是iterable对象而不是列表本身,节省空间
>>> sum(range(4)) # sum把iterable对象作为参数
6
>>> list(range(4)) # list把iterable对象作为参数
[0, 1, 2, 3]
>>> 

break continue 和else子句

>>> for n in range(2, 10):
...     for x in range(2, n):
...             if n % x == 0: # 能被2 ~ n-1整除的数是合数
...                     print(n, 'equals', x, '*', n//x)
...                     break
...     else: # 属于for而不是if
...             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
>>> 
>>> for num in range(2, 10):
...     if num % 2 == 0: # 找到一个偶数,退出此次循环
...             print("Found an even number", num)
...             continue
...     print('Found an odd number', num) # continue未执行时走到这
... 
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9
>>> 

pass子句

语法上需要一个语句,但实际不执行任何动作,用pass

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

用作函数或条件子句占位符,开发者更聚焦抽象层次。程序直接忽而略pass

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

match 子句

接受表达式,其值与n个case语句块给出的模式比较。
与C、java、javascript的switch类似,但其能从值中提取子部分(序列元素或对象属性)并赋值给变量

# 将一个目标值与n个字面值比较
def http_error(status):
	match status:
		case 400:
			return "Bad request"
		case 404:
			return "Not found"
		case 418:
			return "I'm a teapot"
		# 通配符,必定匹配成功。若没有case匹配,分支不会执行	
		case -:
			return "Something's wrong with the internet"						
# |或or匹配多个字面值
case 401 | 403 | 404:
	return "Not allowed"
匹配模式可是:解包赋值,可用于绑定变量
# point is an(x, y) tuple(元组)
match point:
	# 两个字面值
	case(0, 0):
		print("Origin")
	# 一个字面值和一个变量(来自目标值point中的y)	
	case(0, y):
		print(f"Y={y}")
	case(x, 0):
		print(f"X={x}")
	# 类似解包赋值(x, y) = point	
	case(x, y):
		print(f"X={x}, Y={y}")
	case _:
		raise ValueError("Bit a point")				
# 用类结构化数据。可用类名后跟类似构造器的参数列表,能够捕获属性放入变量中
class Point:
	x: int
	y: int
def where_is(point):
	match point:
		case Point(x=0, y=0):
			print("Origin")
		case Point(x=0, y=y):
			print(f"Y={y}")
		case Point(x=x, y=0):
			print(f"X={x}")
		case Point():
			print("Somewhere else")
		case _:
			print("Not a point")					

在属性有排序的内置类(如dataclass)中使用位置参数。可通过类中设置__match_args__特殊属性为模式中属性定义一个专门位置。如果被设置为(x ,y),以下模式均等价(都是将y属性绑定到var变量)
···python
Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)
···

读取模式的推荐方式是将它们看做是你会在赋值操作左侧放置的内容的扩展形式,以便理解各个变量将会被设置的值。 只有单独的名称 (例如上面的 var) 会被 match 语句所赋值。 带点号的名称 (例如 foo.bar)、属性名称 (例如上面的 x= 和 y=) 或类名称 (通过其后的 “(…)” 来识别,例如上面的 Point) 都绝不会被赋值。

# 模式可任意嵌套,由点组成短列表,可如下匹配:
match points:
	case []:
		print("No points")
	case [Point(0, 0)]
		print("The origin")
	case [Point(x, y)]:
		print(f"Single point {x}, {y}")
	case [Point(0, y1), Point(0, y2)]:
		print(f"Two on the Y axis at {y1}, {y2}")
	case _:
		print("Something else")				

给模式添加if子句,成为守护项


match point:
	case Point(x, y) if x == y: 
		print(f"Y=X at {x}")
	case Point(x, y):
		print(f"Not on the diagonal")	

守护项其他关键特性:

  1. 类似于解包赋值,元组和列表模式具有完全相同的含义并且实际上能匹配任意序列。 一个重要的例外是它们不能匹配迭代器或字符串。

  2. 序列模式支持扩展解包操作: [x, y, *rest] 和 (x, y, *rest) 的作用类似于解包赋值。 在 * 之后的名称也可以为 ,因此 (x, y, *) 可以匹配包含至少两个条目的序列而不必绑定其余的条目。

  3. Mapping patterns: {“bandwidth”: b, “latency”: l} captures the “bandwidth” and “latency” values from a dictionary. Unlike sequence patterns, extra keys are ignored. An unpacking like **rest is also supported. (But **_ would be redundant, so it is not allowed.)

  4. 子模式可使用 as 关键字来捕获:

case (Point(x1, y1), Point(x2, y2) as p2): ...

将把输入的第二个元素捕获为 p2 (只要输入是包含两个点的序列)

  1. 大多数字面值是按相等性比较的,但是单例对象 True, False 和 None 则是按标识号比较的。

  2. 模式可以使用命名常量。 这些命名常量必须为带点号的名称以防止它们被解读为捕获变量:

from enum import Enum
class Color(Enum):
    RED = 0
    GREEN = 1
    BLUE = 2

match color:
    case Color.RED:
        print("I see red!")
    case Color.GREEN:
        print("Grass is green")
    case Color.BLUE:
        print("I'm feeling the blues :(")

PEP 636

定义函数

#输出限定数值内的斐波那契数列函数
>>> 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
  1. 函数内的第一条语句是字符串时,该字符串就是文档字符串-docstring,利用文档字符串可自动生成在线文档或打印版文档,开发者在浏览代码时直接查阅文档
    开发者养成在代码中加文档字符串习惯

  2. 函数 执行 时使用函数局部变量符号表,函数变量赋值都存在局部符号表中

  3. 引用变量时

  • 首先在局部符号表里查找变量
  • 然后外层函数局部符号表
  • 再是全局符号表
  • 最后是内置名称符号表
    尽管可以引用全局变量和外层函数的变量,最好不要在函数内直接赋值(除非是 global 语句定义的全局变量,或 nonlocal 语句定义的外层函数变量)
  1. 调用函数将实际参数(实参)引入被调用函数的局部符号表中
    实参使用 按值调用 传递(值 始终是对象 引用 而不是对象的值)

  2. 当一个函数调用另外一个函数时,为该调用创建一个新的局部符号表

  3. 函数定义在当前符号表中
    函数名与函数对象关联在一起
    解释器把函数名指向的对象作为用户自定义函数

  4. 还可用其他名称指向同一个函数对象,并访问访该函数:

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
  1. 没有 return 语句的函数也返回值,这个值比较是 None (是一个内置名称)
    解释器不会输出单独的返回值 None ,可以使用 print()查看该值:
>>> fib(0)
>>> print(fib(0))
None
  1. 不直接输出斐波那契数列运算结果,返回运算结果列表的函数:
>>> 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]
  • return 语句返回函数的值。return 语句不带表达式参数时,返回 None。函数执行完毕退出也返回 None。

  • result.append(a) 语句调用了列表对象 result 的 方法 。方法是“从属于”对象的函数,命名为 obj.methodname,obj 是对象(也可以是表达式),methodname 是对象类型定义的方法名。不同类型定义不同的方法,不同类型的方法名可以相同,且不会引起歧义。(用 类 可以自定义对象类型和方法,详见 类 )示例中的方法 append() 是为列表对象定义的,用于在列表末尾添加新元素。本例中,该方法相当于 result = result + [a] ,但更有效。

函数定义详解

  1. 默认值参数
def ask_ok(prompt, retries=4, reminder='Please try again!'):
    while True:
    	# 关键字 in,确认序列是否包含某值
        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 ValueError('invalid user response')
        print(reminder)
# 只给必选实参
ask_ok('Do you really want to quit?')
Do you really want to quit?ye
True

# 给出一个可选实参
ask_ok('Ok to overwrite the file?', 2)
Ok to overwrite the file?n
False

# 给出所有实参
ask_ok('OK to overwrite the file?', 2, 'Come on only yes or no!')
OK to overwrite the file?e
Come on only yes or no!
OK to overwrite the file?a
Come on only yes or no!
OK to overwrite the file?b
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_10953/2669943829.py in <module>
----> 1 ask_ok('OK to overwrite the file?', 2, 'Come on only yes or no!')

/tmp/ipykernel_10953/1174197352.py in ask_ok(prompt, retries, reminder)
      8         retries = retries - 1
      9         if retries < 0:
---> 10             raise ValueError('invalid user response')
     11         print(reminder)

ValueError: invalid user response

默认值在定义作用域里的函数定义中求值

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

默认值只计算一次
默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果

def f(a, L=[]):
    L.append(a)
    return L
print(f(1))
print(f(2))
print(f(3))
[1]
[1, 2]
[1, 2, 3]

后续调用不共享默认值:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
print(f(1))
print(f(2))
print(f(3))
[1]
[2]
[3]
  1. 关键字参数
    kwarg=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, "!")

一个必选参数(voltage),三个可选参数(state,action,type)

# 1 positional argument 1个位置参数
parrot(1000)
-- This parrot wouldn't voom if you put 1000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !

# 1 keyword argument 1个key-value参数
parrot(voltage=1000)
-- This parrot wouldn't voom if you put 1000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !

# 2 keyword arguments
parrot(voltage=1000000, action="V00000M")
-- This parrot wouldn't V00000M if you put 1000000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !

# 2 keyward arguments 与上一个顺序不一样,但结果一样
parrot(action='V00000M', voltage=1000000)
-- This parrot wouldn't V00000M if you put 1000000 volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's a stiff !

# 3 positionnal arguments
parrot('a million', 'bereft of life', 'jump')
-- This parrot wouldn't jump if you put a million volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's bereft of life !

# 1 positionnal, 1 keyword
parrot('a thousand', state='pushing up the daisies')
-- This parrot wouldn't voom if you put a thousand volts through it.
-- Lovely plumage, the Norwegian Blue
-- It's pushing up the daisies !

无效用法:

#  missing 1 required positional argument: 'voltage'
parrot()

# positional argument follows keyword argument
# 关键子参数后面不能跟一个位置参数
parrot(voltage=5.0, 'dead')

# parrot() got multiple values for argument 'voltage'
# 会重复
parrot(110, voltage=220) 

# parrot() got an unexpected keyword argument 'actor'
parrot(actor='John Cleese')
  • 关键字参数必须跟在位置参数后面
  • 关键字参数都必须匹配一个函数接受的参数(actor 不是函数 parrot 的有效参数)
  • 关键字参数顺序不重要,包括必选参数 (parrot(voltage=1000) 也有效)
  • 不能对同一个参数多次赋值
# 不能对同一个参数多次赋值
def function(a):
    pass
function(0, a=0)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_12651/3300866771.py in <module>
      1 def function(a):
      2     pass
----> 3 function(0, a=0)

TypeError: function() got multiple values for argument 'a'

  • 最后一个形参为 **name 形式时,接收一个字典( 映射类型 — dict
    包含与函数中已定义形参对应之外的所有关键字参数,
    **name形参与*name形参组合使用(*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)
    for kw in keywords:
        print(kw, ":", keywords[kw])

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

cheeseshop("Limburger", "It's very runny, sir.",
          "It's really very, VERY runny, sir.",
          shopkeeper="Michael Palin",
          client="John Cleese",
          sketch="Cheese Shop Sketch")
cheeseshop("Limburger", "It's very runny, sir.",
          "It's really very, VERY runny, sir.",
          shopkeeper="Michael Palin",
          client="John Cleese",
          sketch="Cheese Shop Sketch")
输出:          
-- 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.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch          

关键参数输出结果中顺序与调用顺序一致

  1. 特殊参数
  • 默认情况参数可以按位置或显式关键字传递给 Python 函数
  • 代码易读、高效,最好限制参数的传递方式:只需查看函数定义,即可确定参数项是仅按位置、按位置或关键字,还是仅按关键字传递
# 函数定义
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

/和*可选,符号表明形参如何把参数值传递给函数:位置、位置或关键字。
关键字形参也叫命名形参

3.1 位置或关键字参数
函数定义中未使用/或*时,参数可按位置或关键字传递给函数
3.2 仅位置参数
特定形参可标记为仅限位置,顺序很重要,形参不能用关键字传递,放在/前,/用于逻辑上分割仅限位置形参与其他形参。若函数定义中无/表示没有仅限位置参数

/后可是位置或关键字或仅限关键字形参

3.3 仅限关键字参数
必须以关键字参数形式传递该形参,在参数列表中第一个仅限关键字形参前添加*

3.4 函数示例

def standard_arg(arg):
	print(arg)
def pos_only_arg(arg, /);
	print(arg)
def kwd_only_arg(*, arg):
	print(arg)
def combined_example(pos_only, /, standard, *, kwd_only):
	print(pos_only, standard, kwd_only)		
		
	
# 默认即支持位置和关键字形参
standard_arg(2)
2
standard_arg(arg=2)
2

pos_only_arg(1)
# 函数定义中有/仅限位置形参
pos_only_arg(arg=1)
TypeError                                 Traceback (most recent call last)
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

# 函数i定义通过*仅限关键字形参数
kwd_only_arg(3)
TypeError                                 Traceback (most recent call last)
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

# 使用了全部三种调用惯例
combined_example(1, 2, 3)
TypeError                                 Traceback (most recent call last)
TypeError: combined_example() takes 2 positional arguments but 3 were given

combined_example(1, 2, kwd_only=3)

combined_example(1, standard=2, kwd_only=3)

kwds把name当作键,可能与位置参数name产生潜在冲突

def foo(name, **kwds):
	return 'name' in kwds
# 函数不可能返回True,因为关键字'name'总与第一个形参绑定
foo(1, **{'name': 2})	
	
# 加上/(仅限位置参数)后就可,函数定义把name当作位置参数,'name'也可作为关键字参数的键	
def foo(name, /, **kwds):
    return 'name' in kwds
>>> foo(1, **{'name': 2})
True

仅限位置形参的名称可以在 **kwds 中使用,而不产生歧

3.5 小结
以下用例决定哪些形参可以用于函数定义:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

说明:

  • 使用仅限位置形参,可以让用户无法使用形参名。形参名没有实际意义时,强制调用函数的实参顺序时,或同时接收位置形参和关键字时,这种方式很有用。

  • 当形参名有实际意义,且显式名称可以让函数定义更易理解时,阻止用户依赖传递实参的位置时,才使用关键字。

  • 对于 API,使用仅限位置形参,可以防止未来修改形参名时造成破坏性的 API 变动。

  1. 任意实参列表

调用函数使用任意数量实参是最少见的选项,这些实参包含在元组中。可变数量实参数之前可能有若干个普通参数:

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

variadic实参用于采集传递给函数的所有剩余实参,通常在形参列表的末尾。
*args形参后的任何形参只能是仅限关键字参数,不能用作位置参数

#sep为关键字参数,默认为/
>>> def concat(*args, sep="/"):
...     return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
  1. 解包实参列表
    函数调用要求独立的位置参数,但实参在列表或元组时要执行相反操作。内置的range()函数要求独立的start和stop实参。若不是独立的,则在调用函数时用*操作符把实参从列表或元组解包出来:
list(range(3, 6))	#normal call with separate arguments
[3, 4, 5]
args = [3, 6]
# 用*把args中的元素提取出来作为start和stop
list(range(*args)) * call with arguments unpacked from a list
[3, 4, 5]

字典用**操作符传递关键字参数

def parrot(voltage, state='a stiff', action='voom'):
	print("-- This parrot would'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"}
#使用**解包字典中的key-value
>>> parrot(**d)	
	
  1. lambda表达式

用于创建小巧匿名函数。lambda a, b: a+b返回两个参数的和。
lambda函数可用于任何需要函数对象的地方。
语法上,匿名函数只能是单个表达式。语义上,只是常规函数定义的语法糖。
与嵌套函数定义一样,lambda函数可以引用包含作用域中的变量:

# 用lambda表达式返回函数
def make_incrementor(n):
	return lambda x: x + n
f = make_incrementor(42)
f(0)
42
f(1)
43	

还可把匿名函数用作传递的实参数:

pairs = [(1, 'one'), (2, 'two'), (3, 'there'), (4, 'four')]
pairs.sort(key=lambda pair: pair[1])
pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
  1. 文档字符串
    文档字符串内容和格式的约定:
  • 第一行应为对象用途的简短摘要
    为简洁不要在这里显式说明对象名或类型,可通过其他方式获取这些信息(除非该名称碰巧是描述函数操作的动词)。这一行应以大写字母开头,以句点结尾。
  • 文档字符串为多行时第二行应为空白行,视觉上将摘要与其余描述分开。后面的行可包含若干段落,描述对象的调用约定、副作用等。
  • Python 解析器不会删除 Python 中多行字符串字面值的缩进,文档处理工具应在必要时删除缩进:
    (1)文档字符串第一行 之后 的第一个非空行决定了整个文档字符串的缩进量(第一行通常与字符串开头的引号相邻,其缩进在字符串中并不明显,因此,不能用第一行的缩进)
    (2)然后,删除字符串中所有行开头处与此缩进“等价”的空白符。不能有比此缩进更少的行,但如果出现了缩进更少的行,应删除这些行的所有前导空白符。转化制表符后(通常为 8 个空格),应测试空白符的等效性。

多行文档字符串的一个例子:

>>> 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.
  1. 函数注解
    函数注解
    可选的用户自定义函数类型的元数据完整信息(详见 PEP 3107PEP 484
    标注
    以字典的形式存放在函数的 annotations 属性中,并且不会影响函数的任何其他部分
  • 形参标注的定义方式是在形参名后加冒号,后面跟一个表达式,该表达式会被求值为标注的值
  • 返回值标注的定义方式是加组合符号 ->,后面跟一个表达式,该标注位于形参列表和表示 def 语句结束的冒号之间

下面的示例:
一个必须的参数
一个可选的关键字参数
返回值都带有相应的标注:

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'
  1. 编程风格
    现在你将要写更长,更复杂的 Python 代码,是时候讨论一下 代码风格 了。 大多数语言都能以不同的风格被编写(或更准确地说,被格式化);有些比其他的更具有可读性。 能让其他人轻松阅读你的代码总是一个好主意,采用一种好的编码风格对此有很大帮助。

Python 项目大多都遵循 PEP 8 的风格指南;它推行的编码风格易于阅读、赏心悦目。Python 开发者均应抽时间悉心研读;以下是该提案中的核心要点:

  • 缩进,用 4 个空格,不要用制表符。

  • 4 个空格是小缩进(更深嵌套)和大缩进(更易阅读)之间的折中方案。制表符会引起混乱,最好别用。

  • 换行,一行不超过 79 个字符。

    这样换行的小屏阅读体验更好,还便于在大屏显示器上并排阅读多个代码文件。

  • 用空行分隔函数和类,及函数内较大的代码块。

  • 最好把注释放到单独一行。

  • 使用文档字符串。

  • 运算符前后、逗号后要用空格,但不要直接在括号内使用: a = f(1, 2) + g(3, 4)。

  • 类和函数的命名要一致;按惯例,命名类用 UpperCamelCase,命名函数与方法用 lowercase_with_underscores。命名方法中第一个参数总是用 self (类和方法详见 初探类)。

  • 编写用于国际多语环境的代码时,不要用生僻的编码。Python 默认的 UTF-8 或纯 ASCII 可以胜任各种情况。

  • 同理,就算多语阅读、维护代码的可能再小,也不要在标识符中使用非 ASCII 字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值