顺序执行
https://www.liujiangblog.com/course/python/26
# 代码执行过程基本原则:
# 普通语句,直接执行;
# 碰到函数,将函数体载入内存,并不直接执行
# 碰到类,执行类内部的普通语句,但是类的方法只载入,不执行
# 碰到if、for等控制语句,按相应控制流程执行
# 碰到@,break,continue等,按规定语法执行
# 碰到函数、方法调用等,转而执行函数内部代码,执行完毕继续执行原有顺序代码
import os # 1
print('<[1]> time module start') # 2
class ClassOne():
print('<[2]> ClassOne body') # 3
def __init__(self): # 10
print('<[3]> ClassOne.__init__')
def __del__(self):
print('<[4]> ClassOne.__del__') # 101
def method_x(self): # 12
print('<[5]> ClassOne.method_x')
class ClassTwo(object):
print('<[6]> ClassTwo body') # 4
class ClassThree():
print('<[7]> ClassThree body') # 5
def method_y(self): # 16
print('<[8]> ClassThree.method_y')
class ClassFour(ClassThree):
print('<[9]> ClassFour body') # 6
def func():
print(" function func")
if __name__ == '__main__': # 7
print('<[11]> ClassOne tests', 30 * '.') # 8
one = ClassOne() # 9
one.method_x() # 11
print('<[12]> ClassThree tests', 30 * '.') # 13
three = ClassThree() # 14
three.method_y() # 15
print('<[13]> ClassFour tests', 30 * '.') # 17
four = ClassFour()
four.method_y()
print('<[14]> evaltime module end') # 100
-----------------------------------------------------------
<[1]> time module start
<[2]> ClassOne body
<[6]> ClassTwo body
<[7]> ClassThree body
<[9]> ClassFour body
<[11]> ClassOne tests ..............................
<[3]> ClassOne.__init__
<[5]> ClassOne.method_x
<[12]> ClassThree tests ..............................
<[8]> ClassThree.method_y
<[13]> ClassFour tests ..............................
<[8]> ClassThree.method_y
<[14]> evaltime module end
<[4]> ClassOne.__del__
__name__ 和__main__关系
https://www.cnblogs.com/chenhuabin/p/10118199.html
if __name__ == '__main__':
__name__是所有模块都会有的一个内置属性
当哪个模块(脚本)被直接执行时,该模块“__name__”的值就是“__main__”,
当被导入另一模块(脚本)时,“__name__”的值就是模块的真实名称。
所以当运行脚本时,自己脚本下if __name__ == '__main__':为True,后面的语句继续执行,
如果被其他脚本import或调用时,为Flase,后面语句不执行。
break只能退出一层循环,对于多层嵌套循环,不能全部退出。
continue不会退出和终止循环,只是提前结束当前轮次的循环
默认参数
# 默认参数必须在位置参数后面
# 有多个默认参数的时候,通常将更常用的放在前面,变化较少的放后面。
# 尽量给实际参数提供默认参数名。
def power(x, n = 2):
return x**n
ret1 = power(10) # 使用默认的参数值n=2
ret2 = power(10, 4) # 将4传给n,实际计算10**4的值
动态参数
# 必须放在所有的位置参数和默认参数后面!
# *args:一个星号表示接收任意个参数。
# **kwargs:两个星表示接受键值对的动态参数
def func(a, b, c=1, *args, **kwargs):
print('c的值是:', c)
for arg in args:
print(arg)
for kwg in kwargs:
print(kwg, kwargs[kwg])
lis = ['aaa', 'bbb', 'ccc']
dic = {
'k1': 'v1',
'k2': 'v2'
}
func(1, 2, *lis, **dic)
-----------------------------------------------
c的值是: aaa
bbb
ccc
k1 v1
k2 v2
全局变量 global
total = 0 # total是一个全局变量
print("函数外的total的内存地址是: ", id(total))
def plus( arg1, arg2 ):
global total # 使用global关键字申明此处的total引用外部的total
total = arg1 + arg2
print("函数内局部变量total= ", total)
print("函数内的total的内存地址是: ", id(total))
return total
plus(100, 200)
print("函数外部全局变量total= ", total)
print("函数外的total的内存地址是: ", id(total))
---------------------------
函数外的total的内存地址是: 140712987878000
函数内局部变量total= 300
函数内的total的内存地址是: 2464464009200
函数外部全局变量total= 300
函数外的total的内存地址是: 2464464009200
# global
a = 1
print("1函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2
print("2函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
global a # 注意这行
a = 3
print("3函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("4函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("5函数outer执行完毕,全局变量a的内存地址: ", id(a))
--------------------------------------
1函数outer调用之前全局变量a的内存地址: 140712987878032
2函数outer调用之时闭包外部的变量a的内存地址: 140712987878064
3函数inner调用之后闭包内部变量a的内存地址: 140712987878096
4函数inner调用之后,闭包外部的变量a的内存地址: 140712987878064
5函数outer执行完毕,全局变量a的内存地址: 140712987878096
# nonlocal
a = 1
print("1函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2
print("2函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
nonlocal a # 注意这行
a = 3
print("3函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("4函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("5函数outer执行完毕,全局变量a的内存地址: ", id(a))
---------------------------
1函数outer调用之前全局变量a的内存地址: 140712987878032
2函数outer调用之时闭包外部的变量a的内存地址: 140712987878064
3函数inner调用之后闭包内部变量a的内存地址: 140712987878096
4函数inner调用之后,闭包外部的变量a的内存地址: 140712987878096
5函数outer执行完毕,全局变量a的内存地址: 140712987878032
# Python函数的作用域取决于其函数代码块在整体代码中的位置,而不是调用时机的位置
name ='jack'
def f1():
print(name)
def f2():
name = 'eric'
f1()
f2()
----------------------------------------
jack
range()
# 默认从0开始,到参数减1,左闭右开
a = ['Google', 'Baidu', 'Huawei', 'Taobao', 'QQ']
for i in range(len(a)):
print(i, a[i])
--------------------------------------
1 Baidu
2 Huawei
3 Taobao
4 QQ
# 切片
for i in range(10,1,-2):
print(i)
------------------------------------
10
8
6
4
2
lambda匿名函数
# lambda 参数: 表达式。
# 匿名函数作为别的函数的返回值返回
def add(string, i):
return lambda: int(string) + i
>>> f = lambda x: x * x
>>> f
at 0x3216fef44>
>>> f(6)
36
推导式
# 1. 列表推导式
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [a + b for a in ‘123' for b in ‘abc']
['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']
# 2. 字典推导式
>>> dic = {x: x**2 for x in (2, 4, 6)}
>>> dic
{2: 4, 4: 16, 6: 36}
>>> type(dic)
# 3. 集合推导式
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'d', 'r'}
>>> type(a)
# 4. 元组推导式
tup = tuple(x for x in range(9))
print(tup)
print(type(tup))
------------------------
结果:
(0, 1, 2, 3, 4, 5, 6, 7, 8)
迭代器
# Python中,list/tuple/string/dict/set/bytes都是可以迭代的数据类型。
# 可以通过collections模块的Iterable类型来判断一个对象是否可迭代:
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False
# 通常要实现两个基本的方法:iter() 和 next()。
>>> lis=[1,2,3,4]
>>> it = iter(lis)
>>> type(it)
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
4
>>> next(it)
Traceback (most recent call last):
File "", line 1, in
StopIteration
# for循环遍历迭代器:
lis = [1,2,3,4]
it = iter(lis) # 创建迭代器对象
for x in it: # 使用for循环遍历迭代对象
print (x, end=" ")
generator生成器
# 数量巨大,放入内存,压力大。不必创建完整的元素集合,推算出来到哪就计算到哪个。
# 斐波那契函数
def fibonacci(n):
a, b, counter = 0, 1, 0
while True:
if counter > n:
return
yield a # yield返回的函数变成一个生成器
a, b = b, a + b
counter += 1
fib = fibonacci(10) # fib是一个生成器
print(type(fib))
for i in fib:
print(i, end=" ")