Python 编程笔记(小白初学篇)
一、准备工作
1. 下载安装
好用博客:https://blog.csdn.net/yugemiren/article/details/104866397
官网:https://www.python.org
正如博客所言,下载一个低版本的就行。很快的。
2. 实现快捷键清屏
当然,这里指的是windows,Python 并没有自带清屏快捷键,网上这招也许是大佬自己搞出来的。有很多文章都讲如何操作的,操作方法大同小异,本质上都是一样的,这里挑了个简洁的,链接如下:
https://www.cnblogs.com/ningmengcaokanyu/p/10297840.html
大致分为这几步:
1.在Python\Lib\idlelib下,新建一个ClearWindow.py文件(没有时就新建)
2.Python\Lib\idlelib下修改config-extensions.def ,在末尾添加如下内容
关于第二步,若改不了的话,可以以管理员的身份打开powershell,然后输入 notepad xx\Python\Lib\idlelib\config-extensions.def
进行修改,之后保存。
这块先当草稿存着
import os #从标准库导入os模块
os.chdir('F:\HeadFirstPython\chapter3')
#切换到包含数据文件的文件夹
C:\>python he11o.py #windows下执行python脚本
$ python he11o.py #Linux 下执行python脚本
#!/usr/bin/env python
#Linux 下,上面那行放xx.py首行,即可像.sh脚本执行
## 分解字符串 ##
import re #正则表达式的包
list=re.split(r'[;,\s]\s*', line) #不含分隔符
list=re.split(r'(;|,|\s)\s*', line) #包含分隔符
import os; os.chdir(r'C:\Users\OHanlon\Documents\python')
#设置当前路径
import os; os.getcwd() #打印当前路径
*["seven", 18, 'alex'] # *作用是将列表解开成独立的参数。
**{'a' : 4, 'b' : 3} # **作用是将字典解开成独立的元素。
二、基础知识
1. 快应用
这部分记录一下常用的符号,命令,函数..反正就是几个汇总的表格,方便以后快速使用。
常用符号及含义
符号 | 含义 | 符号 | 含义 |
---|---|---|---|
' |
字符串 | " |
字符串 |
\ |
转义 | \ |
续行符(在行尾时) |
+ | 加 | - | 减 |
* | 乘 | / | 除 |
** | 幂乘 | // | 整除 |
% | 取模 | = | 赋值 |
+= | 加法赋值 | -= | 减法赋值 |
*= | 乘法赋值 | /= | 除法赋值 |
%= | 取模赋值 | //= | 整除赋值 |
**= | 幂乘赋值 | ||
!= | 不等? | == | 相等? |
< | 小于? | > | 大于? |
<= | 小于等于? | >= | 大于等于? |
& | 位与 | ` | ` |
^ | 位异或 | ~ | 位取反 |
<< | 左移 | >> | 右移 |
and | 布尔与 | or | 布尔或 |
not | 布尔非 | in | 在里面? |
not in | 不在里面? | is | 引用的同一对象? |
is not | 引用不同对象? | ||
常用函数及含义 |
import math
函数 | 含义 | 函数 | 含义 |
---|---|---|---|
pow(a, n) |
a 的 n 次方 | abs(a) |
a 的绝对值 |
round(a) |
a 四舍五入 | int(a) |
a 转换为整数 |
math.ceil(a) |
a 上入整数 | long(a) |
a 转换为长整数 |
math.floor(a) |
a 下舍整数 | float(a) |
a 转换为浮点数 |
input() |
获取输入 | str(a) |
a 转换为字符串 |
raw_input() |
获取输入,返回字符串 | repr(object) |
返回值的字符串表示形式 |
range(start, stop[, step]) |
计数从 start 开始。默认是从 0 开始。 | 计数到 stop 结束,但不包括 stop。 | 步长,默认为1。 |
math.sqrt(a) |
a 开根号 | cmath.sqrt(a) |
a 复数开根号 |
math.exp(a) |
e的a次幂 | math.fabs(a) |
a 的绝对值 |
math.log10(a) |
以10为基数的a的对数 | math.log(a) |
以e为基数的a的对数 |
max(a1,a2,a3...) |
返回给定参数(可为序列)的最大值 | min(a1,a2,a3...) |
返回给定参数的最小值 |
math.modf(a) |
返回x的整数部分与小数部分, | 两部分的数值符号与x相同, | 整数部分以浮点型表示。 |
acos(x) |
反余弦弧度 | asin(x) |
反正弦弧度 |
atan(x) |
反正切弧度 | atan2(y,x) |
y/x 的反正切 |
cos(x) |
弧度的余弦 | sin(x) |
弧度的正弦 |
tan(x) |
弧度的正切 | hypot(x,y) |
欧几里德范数 sqrt(x*x + y*y) |
degrees(x) |
弧度转角度 | radians(x) |
角度转弧度 |
math.pi |
圆周率 | math.e |
数学常量e |
随机数函数 |
import random
函数 | 描述 |
---|---|
choice(seq) |
从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。 |
randrange ([start,] stop [,step]) |
从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1 |
random() |
随机生成下一个实数,它在[0,1)范围内。 |
seed([x]) |
改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。 |
shuffle(lst) |
将序列的所有元素随机排序 |
uniform(x, y) |
随机生成下一个实数,它在[x,y]范围内。 |
python 的格式化输出
这块之所以放在这里而不放在下面,是因为这个比较常用,而且都是表格。
Python的字符串格式化有两种方式: %方式、format方式。百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存。
1 %方式
%[(name)][flags][width].[precision]typecode
(name)
【可选】用于选择指定的keyflags
【可选】可供选择的值有:
flags | 含义 |
---|
- | 右对齐;正数前加正好,负数前加负号;
-
| 左对齐;正数前无符号,负数前加负号;
空格 | 右对齐;正数前加空格,负数前加负号;
0 | 右对齐;正数前无符号,负数前加负号;用0填充空白处 -
width
【可选】占有宽度,默认有多长占多长 -
.precision
【可选】小数点后保留的位数 -
typecode
【必选】
typecode | 含义 |
---|---|
s | 获取传入对象的__str__ 方法的返回值,并将其格式化到指定位置 |
r | 获取传入对象的__repr__ 方法的返回值,并将其格式化到指定位置 |
c | 整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111 (py27则只支持0-255);字符:将字符添加到指定位置 |
o | 将整数转换成 八 进制表示,并将其格式化到指定位置 |
x | 将整数转换成十六进制表示,并将其格式化到指定位置 |
d | 将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置 |
e | 将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e) |
E | 将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E) |
f | 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位) |
F | 同上 |
g | 自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;) |
G | 自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;) |
% | 当字符串中存在格式化标志时,需要用 %%表示一个百分号 |
下面整几个例子: |
>>> print("I am %s" % "Alex")
I am Alex
>>> print("I am %s age %d" % ("Alex", 18))
I am Alex age 18
>>> print("I am %(name)s age %(age)d" % {"name": "Alex", "age": 18})
I am Alex age 18
>>> print("percent %.2f" % 99.97623)
percent 99.98
>>> print("I am %(pp).2f %%" % {"pp": 123.425556, })
I am 123.43 %
2 format 方式
[[fill]align][sign][#][0][width][,][.precision][type]
fill
【可选】空白处填充的字符align
【可选】对齐方式(需配合width使用)
align | 含义 |
---|---|
< | 内容左对齐 |
|内容右对齐(默认)
=|内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
^|内容居中
sign
【可选】有无符号数字
align | 含义 |
---|---|
+ | 正号加正,负号加负; |
- | 正号不变,负号加负; |
空格 | 正号空格,负号加负; |
#
【可选】对于二进制、八进制、十六进制,如果加上#,会显示0b/0o/0x
,否则不显示,
【可选】为数字添加分隔符,如:1,000,000width
【可选】格式化位所占宽度.precision
【可选】小数位保留精度type
【可选】格式化类型
传入参数类型 | type |
---|---|
传入” 字符串类型 “的参数 | s,格式化字符串类型数据 空白,未指定类型,则默认是None,同s |
传入“ 整数类型 ”的参数 | b,将10进制整数自动转换成2进制表示然后格式化 c,将10进制整数自动转换为其对应的unicode字符 d,十进制整数 o,将10进制整数自动转换成8进制表示然后格式化; x,将10进制整数自动转换成16进制表示然后格式化(小写x) X,将10进制整数自动转换成16进制表示然后格式化(大写X) |
传入“ 浮点型或小数类型 ”的参数 | e, 转换为科学计数法(小写e)表示,然后格式化; E, 转换为科学计数法(大写E)表示,然后格式化; f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化; F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化; g, 自动在e和f中切换 G, 自动在E和F中切换 %,显示百分比(默认显示小数点后6位) |
下面整几个例子:
>>> "I am {}, age {}, {}".format("seven", 18, 'Alex')
'I am seven, age 18, Alex'
>>> "I am {0}, age {1}, really {0}".format(*["seven", 18])
'I am seven, age 18, really seven'
>>> "I am {name}, age {age}, really {name}".format(name="seven", age=18)
'I am seven, age 18, really seven'
>>> "I am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
'I am seven, age 18, really seven'
>>> "I am {0[0]}, age {1[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
'I am 1, age 22, really 3'
>>> "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
'numbers: 1111,17,15,f,F, 1587.623000%'
>>> "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
'numbers: 1111,17,15,f,F, 1500.000000%'
>>> "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
'numbers: 1111,17,15,f,F, 1500.000000%'
数据类型转换
函数 | 描述 |
---|---|
int(x [,base]) |
将x转换为一个整数 |
float(x) |
将x转换到一个浮点数 |
complex(real [,imag]) |
创建一个复数 |
str(x) |
将对象 x 转换为字符串 |
repr(x) |
将对象 x 转换为表达式字符串 |
eval(str) |
用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) |
将序列 s 转换为一个元组 |
list(s) |
将序列 s 转换为一个列表 |
set(s) |
转换为可变集合 |
dict(d) |
创建一个字典。d 必须是一个 (key, value)元组序列。 |
frozenset(s) |
转换为不可变集合 |
chr(x) |
将一个整数转换为一个字符 |
ord(x) |
将一个字符转换为它的整数值 |
hex(x) |
将一个整数转换为一个十六进制字符串 |
oct(x) |
将一个整数转换为一个八进制字符串 |
2. 输入输出
python 简单的输入输出如下:
>>> a=input('please input the value of a: ')
please input the value of a: 12
>>> print(a)
12
当你想知道一个变量的值是多少时,可能会对它是整型还是长整型感兴趣。这可以通过两种机制来实现,实际上是值被转换为字符串的两种机制。可以通过以下两个函数来使用这两种机制:一是通过str
函数,它会把值转换为合理形式的字符串,以便用户可以理解,而repr
会创建一个字符串,它以合法的Python表达式的形式来表示值。下面是一些例子
>>> 'hello world!'
'hello world!'
>>> print('hello world!')
hello world!
>>> print(repr('hello world!'))
'hello world!'
>>> print(str('hello world!'))
hello world!
关于两个input (input 和 raw_input) ,假设有这样一个脚本:
name = input( "what is your name? ")
print "He11o. " + name + " !"
------------------
What is your name? "Gumby"
#输入需加引号,用raw_input()则不需
He11o. Gumby!
++++++++++++++++++++++++++++
>>input( "Enter a number: ")Enter a number: 3
3
>>>raw_input( "Enter a number: ")Enter a number: 3
'3'
raw_input 会把所有数据当作原始输入存放在字符串中。也就是说,使用这俩input的时候,可以按照如下规则:input 对值进行操作,raw_input 对字符串进行操作。
'''
跨行书写字符串,当然最后也得用'''
将其引起来。普通字符串也可以跨行(换行的时候加个\
)。如果一行之中最后一个字符是反斜线\
,那么,换行符本身就“转义”了,也就是被忽略了。
>>> print('C:\nowhere')
C:
owhere
>>> print(r'C:\nowhere')
C:\nowhere
原始字符串,其最后一个字符不可以是反斜杠\
格式化输出见上面。
3. 数据类型
Python基本数据类型一般分为:数字、字符串、列表、元组、字典、集合这六种基本数据类型。
-
标准整型:
int
,在大多数32位机器上标准整型取值范围是 \(-2^{31}\) 到 \(2^{31}-1\),也就是-2147483648~2147483647
,如果在64位机器使用64位编译器,那么这个系统的标准整型将是64位。 -
布尔型:
bool
,从 Python2.3 开始 Python 中添加了布尔类型。布尔类型有两种True
和False
。对于没有__nozero__
方法的对象默认是True。对于值为0的数字、空集(空列表、空元组、空字典等)在Python中的布尔类型中都是False。 -
浮点型:
float
,每个浮点型占8个字节(64位),完全遵守IEEE754号规范(52M/11E/1S),其中52个位用于表示底,11个位用于表示指数(可表示的范围大约是 \(±10^{308.25}\)),剩下的一个位表示符号。这看上去相当完美,然而,实际精度依赖于机器架构和创建Python解释器的编译器。浮点型值通常都有一个小数点和一个可选的后缀e(大写或小写,表示科学计数法)。在e和指数之间可以用正(+)或负(-)表示指数的正负(正数的话可以省略符号)。经过Python实测浮点型默认长度是24字节。 -
复数类型:
complex
在复数中虚数不能单独存在,它们总是和一个值为0.0的实数部分一起来构成一个复数。复数由实数部分和虚数部分构成。表示虚数的语法:real+imagj
。实数部分和虚数部分都是浮点型。虚数部分必须有后缀j
或J
。
a=10 #数字
str='I am a string' #字符串
list1 = ['Google', 'Runoob', 1997, 2000] #列表
tup1 = ('Google', 'Runoob', 1997, 2000) #元组
dict2 = { 'abc': 123, 98.6: 37 } #字典
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} #集合
4. 条件与循环语句
Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。
1、条件判断 - if 语句
if condition_1:
statement_block_1
elif condition_2:
statement_block_2
else:
statement_block_3
- Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else。
- 每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。
- 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
- 在Python中没有switch – case语句。
2、循环语句 - while
while 判断条件(condition):
执行语句(statements)……
while … else :在条件语句为 false 时执行 else 的语句块。
while <expr>:
<statement(s)>
else:
<additional_statement(s)>
3、循环语句 - for
for <variable> in <sequence>:
<statements>
else:
<statements>
其他控制语句:
语句 | 含义 |
---|---|
break | break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。 |
continue | continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。 |
pass | pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句。 |
5. 关于文件
1、open函数用来打开文件,语法如下:open(name[, mode[, buffering]])
其使用文件名(name)作为一个强制参数,模式(mode)和缓冲(buffering)参数都是可选的。
1)open 函数中模式参数常用值
值 | 描述 |
---|---|
'r' |
读模式 ,默认参数 |
'x' |
写模式,新建一个文件,如果该文件已存在则会报错。 |
'w' |
写模式 |
'a' |
追加模式 |
'b' |
二进制模式(可添加到其他模式中使用) |
'+' |
读/写模式(可添加到其他模式中使用) |
注:'b' 模式改变处理文件的方法。一般来说,Python 假定处理的是文本文件(包含字符)。若要处理二进制文件,那么应该在模式参数中增加'b' ,例如'rb' 。 |
|
2)open函数的第3个参数(可选)控制着文件的缓冲。如果参数是0(或者是False),IO(输入/输出)就是无缓冲的(所有的读写操作都直接针对硬盘)﹔如果是1(或者是True),IO就是有缓冲的(意味着Python使用内存来代替硬盘,让程序更快,只有使用flush或者close时才会更新硬盘上的数据。大于1的数字代表缓冲区的大小(单位是字节),-1(或者是任何负数)代表使用默认的缓冲区大小。 |
读写简单示例:
# write
f=open('somefile.txt','w')
f.write('Hello, ')
f.write('World!')
f.close();
-----------------------
# read
f=open('somefile.txt','r');
f.read(4) #读取4个字符
f.read() #读取剩下的字符
f.close()
2、seek 函数来随机访问,seek函数的一般用法为:seek(offset[, whence])
这个方法把当前位置(进行读和写的位置)移动到由offset 定义的位置。
offset:从开始位置的偏移量,也就是代表需要移动偏移的字节数。
whence:给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
tell()
返回当前游标在文件中的位置。
3、读写行
file.readline()
读取单独的一行(从当前位置开始直到一个换行符出现,也读取这个换行符。file.readline(5)
读取这一行中前五个字符。file.readlines()
读取一个文件中所有行并将其作为列表返回。
writelines
方法和readlines
相反:传给它一个字符串的列表(实际上任何序列或者可迭代的对象都行),它会把所有的字符串写人文件(或流)。注意,程序不会增加新行,需要自己添加。没有writeline方法,因为能使用write
。
6. 关于函数
定义一个函数的格式:
def 函数名(参数列表):
函数体
return *
以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
关于在一个脚本中调用另一个脚本中的函数:
比如我想在脚本 c.py 中调用脚本 a.py 中的函数 fun_c,那么我需要在脚本c.py中from a import fun_c
,前提是当前工作路径必须是a.py所在路径,更改工作路径的方式为:os.chdir(r'C:\Users\OHanlon\Documents\python')
值得注意的一点,脚本运行之后,工作路径就变成了其所在路径。
关于参数传递
在 python 中,strings, tuples, 和 numbers 是不可更改(immutable)的对象,而 list,dict 等则是可以修改的(mutable)对象。
python 函数的参数传递:
-
不可变类型:类似 C++ 的值传递,如 整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a))内部修改 a 的值,则是新生成来一个 a。
-
可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响。
关于函数参数
以下是调用函数时可使用的正式参数类型:必需参数、关键字参数、默认参数、不定长参数。
- 必需参数:必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
- 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
#!/usr/bin/python3
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
- 默认参数:调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:
def printinfo( name, age = 35 ):
- 不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:
加了星号*
的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
-----------------------------
#!/usr/bin/python3
# 可写函数说明
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
for var in vartuple:
print (var)
return
# 调用printinfo 函数
printinfo( 10 )
printinfo( 70, 60, 50 )
加了两个星号 **
的参数会以字典的形式导入。
def functionname([formal_args,] **var_args_dict ):
"函数_文档字符串"
function_suite
return [expression]
声明函数时,参数中星号 *
可以单独出现,如果单独出现星号 *
后的参数必须用关键字传入。
>>> def f(a,b,*,c):
... return a+b+c
...
>>> f(1,2,3) # 报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
匿名函数
python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
- 语法,lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
#!/usr/bin/python3
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
强制位置参数
Python3.8 新增了一个函数形参语法 /
用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。
在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 或 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
-----------------------------
f(10, 20, 30, d=40, e=50, f=60) # 正确
f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式
7. 关于调试
1 在所需要调试的地方加入如下代码:
import pdb
pdb.set_trace()
2 调试代码常用命令:
命令 | 含义 |
---|---|
break / b | 设置断点 |
command / c | 继续执行程序 |
list / l | 查看当前行的代码段 |
step / s | 进入函数 |
return / r | 执行代码直到从当前函数返回 |
exit / q | 中止并退出 |
next / n | 执行下一行 |
pp | 打印变量的值 |
help | 帮助 |