Python 进阶教程(1)——语法

关于Bukkit插件的教程,因为电脑配置有限,并且本人最早是在用PHP语言开发的PocketMine上开发软件,Java 和 PHP 的语法已早忘得差不多了,啥时候有时间再慢慢钻研。

本篇主要面向一些学了一些基础Python,但是高级语法以及其他语法的用法不太熟悉的人的一些教程。

三元表达式

a = "This is True" if True else "This is False"Code language: PHP (php)

这是一个典型的三元表达式(运算符),在php中如下表示:

a = "This is True" ? true : "This is False";Code language: JavaScript (javascript)

Python中实际等效于:

if True:
    a = "This is True"
else:
    a = "This is False"Code language: PHP (php)

其格式为

[执行语句,判断为true时执行] if [判断语句,与if的判断格式相同] else [执行语句,判断为false时执行]Code language: CSS (css)

其中“[]”不用照打。此判断式将根据判断结果返回一个执行语句的执行结果。

你可以通过该语句简写一个只有一行(除去if一行)的if语句,十分实用。

列表解析式

顾名思义,用来通过一个简短的语句解析列表:

>>> my_list = [1,2,3,4,5,6,7,8,9,10]
>>> my_list = [i-1 for i in my_list]
>>> print(my_list)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]Code language: PHP (php)

“>>>”表示输入内容(为空格后面一串),用于区分输入代码与输出内容。

可以看到经过列表解析式后原列表中的数据每一个都减去了1。

列表解析式用于更改某一列表全体元素的元素值,其格式为

[DoSth for variable in aList]Code language: JSON / JSON with Comments (json)

(其中”[“不可省),该式等效于:

for variable in range(len(aList)):
    aList[variable] = DoSth

DoSth表示任意一个可以返回内容的东西(即使返回None),如x-1,myFunction(x)等,在执行该DoSth后会更改当前元素的值为DoSth的返回内容。

variable表示任意一变量(定义与未定义都可以),可以随意更改变量名

aList表示一个列表对象或字典、元组对象,使用元组或字典对象时会自动将该对象转换为列表对象(转换后字典对象的每一元素为原字典的每一key值)

函数参数:包裹位置参数、包裹关键字参数

很好区分这俩货:一个是“*”,一个是“**”

不要将包裹关键字参数和幂运算符搞混。

def a(x, x2, x3=1, x4=2, *arg, **args):
    print(x, x2, x3, x4, arg, args)

a(1, 2, 3, 4, 5,5,5, u=7,p=8)

输出: 1 2 3 4 (5, 5, 5) {'u': 7, 'p': 8}Code language: PHP (php)

其中前面几个(x, x2)是默认参数,可写可不写

后面两个(x3, x4)是关键字参数,当执行函数时没有关键字传入时默认按照顺序对应。

”*arg“表示除了默认函数以外的其他不带关键字的参数,”arg“的类型是一个元组。

”**args“表示除了默认关键字参数以外的其他关键字参数,是一个字典对象。

这些参数表达式可以很好的缩减注释函数时多参数情况,让编写者自己去查文档,并且可以避免多参数时出现参数过多而报错。(但是某些函数(如tkinter, PyQt5, PySide2里众多函数)因为是由C/C++的dll文件移植到Python,必须给出默认参数才能执行,因此多参数也会报错。)

函数修饰器

这个东西不常用,也不算很使用,主要用于执行某一函数前提前执行某些代码。

def func(fn):
  def funcA(*arg, **args):
    print("开始执行")
    returnValue = fn(*arg, **args)
    print("结束执行,返回:", returnValue)
  return funcA

@func
def MyThirdFunc():
  print("被修饰的函数执行")Code language: PHP (php)

函数修饰器会将被修饰的函数作为一个变量传给函数修饰器的函数,并函数修饰器内执行某些代码。

等效于:

def func(fn):
  def funcA(*arg, **args):
    print("开始执行")
    returnValue = fn(*arg, **args)
    print("结束执行,返回:", returnValue)
  return funcA

def MyThirdFunc():
  print("被修饰的函数执行")

MyThirdFunc = func(MyThirdFunc) #原函数修饰器一行必须放在定义函数之后运行Code language: PHP (php)

修饰器一般用于查询某些函数导致的报错(在函数参数器中写try而不在函数中写try更方便美观)等多方面。用其也可以实现重载。

元组、列表元素赋值

当你有一个长度(length)为2的元组/列表,并且你想通过变量来迅速表示他们,你可能会:

a = ("apple", "banana")
V1 = a[0]
V2 = a[1]Code language: JavaScript (javascript)

但是如果你读过某一教程的socket章节,你发现他可以这样进行赋值:

a = ("apple", "banana")
V1, V2 = aCode language: JavaScript (javascript)

globals()和locals()

globals函数将返回当前环境(全局)的所有变量与他的值,类型为字典对象(dict object):

而locals函数返回当前环境(局部)的所有变量与他的值,类型同上:

全局即全局环境,局部即某一class或def内的变量。当在执行某一局部部分的代码时,局部环境的搜索优先级大于全局:

(就是当出现相同变量名时Python会优先使用局部环境的变量)

如何在局部访问全局变量?这就得提到global关键字了:

你惊奇的发现,局部变量同步到了全局变量,这就是global的作用,他后面只能接上全局变量,同时必须放在def后一行,可以跟多个全局变量名。

套娃

如果你见到过nonlocal,他和global一样同属保留关键字,但是他的作用是什么?

当你在函数内套娃一个函数(下面称函数a为父函数,函数b为子函数),子函数能访问父函数的所有参数,除了环境变量。

但是当你尝试在使用父函数的变量时且后文对该变量名进行了更改,就会报错:

因为Python检查到了你在后文对子函数内m2变量进行了更改,但之前在子函数中并没有声明m2变量,所以就会检查到在定义之前使用(姑且算一个Bug)

但当你加上nonlocal之后就会恢复正常,此时子函数会默认已经定义了m2变量,其值为父函数定义的m2。

可以将nonlocal看作套娃版global和locals()的关系。

其用于在子函数需要对父函数局部变量更改时提前声明。(当然你只需要调用访问他就不需要做声明)

发表回复