一、递归
1.1 什么是函数递归
函数的嵌套调用是:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数的过程中,又直接或间接地调用了它自身。
def foo():
print('from foo')
foo()
foo() # 进入死循环
如果递归函数不断地调用函数自身,那么这个递归函数将会进入一个死循环,因此我们应该给递归函数一个明确的结束条件。
1.2 直接调用
直接调用指的是:直接在函数内部调用函数自身
count=1
def f1():
global count # 下面的count是全局的count
count += 1 # 2 # 3
print(count) # 2 # 3
f1()
f1()
1.3 间接调用
间接调用指的是:不在原函数体内调用函数自身,而是通过其他方法间接调用函数自身
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
bar()
1.4 递归的核心
递归必须要有两个明确的阶段:
1、递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
2、回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯
递进的精髓在于通过不断的重复逼近一个最终的结果,问题规模越来越小(不一定要真正的达到):设置一个条件,能够让最后一次函数调用结束
# 递归代码(递归更多的是一种思想,用来解决某种问题)
count = 1 # 2 # 3
def f1():
global count # 下面的count是全局的count
if count > 100: # 用来结束最后一次函数调用的条件
return
count += 1 # 2 # 3
print(count) # 2 # 3
f1()
f1()
二、内置函数
2.1 掌握
1、bytes() 解码字符
res='你好'.encode('utf8')
print(res) # b'\xe4\xbd\xa0\xe5\xa5\xbd'
res=bytes('你好',encoding='utf8')
print(res) # b'\xe4\xbd\xa0\xe5\xa5\xbd'
2、chr()/ord()
chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字
print(chr(65)) # A
print(prd('A')) # 65
3、enumerate() 带有索引的迭代
l=['a','b','c']
for i in enumerate(l):
print(i)
--------------------------------------------------------------------------
(0, 'a')
(1, 'b')
(2, 'c')
# 获取索引和值
for ind, value in enumerate([1, 2, 3]):
print(ind, value)
--------------------------------------------------------------------------
0 1
1 2
2 3
4、divmod() 分栏
print(divmod(10,3)) # 获取10/3的整数和余数
--------------------------------------------------------------------------
(3,1)
5、eval() 把字符串翻译成数据类型
lis='[1,2,3]'
lis_eval=eval(lis)
print(lis_eval) # [1,2,3]
6、hash() 是否可哈希
print(hash(1)) # 1
2.2 了解
1、abs() 求绝对值
print(abs(-13)) # 13
2、all() 可迭代对象内元素全为真,则返回真
print(all([1,2,3,0])) # False
print(all([])) # True
3、any()
可迭代对象中有一元素为真,则为真
print(any([1, 2, 3, 0])) # True
print(any([])) # False
4、bin()/oct()/hex()
二进制、八进制、十六进制转换
print(bin(17)) # 0b10001
print(oct(17)) # 0o21
print(hex(17)) # 0x11
5、dir() 列举出所有time的功能
import time
print(dir(time))
--------------------------------------------------------------------------
['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname', 'tzset']
6、frozenset() 不可变集合
s=frozenset({1,2,3})
print(s) # frozenset({1,2,3})
7、globals()/locals() 查看全局名字/查看当前局部名字
8、pow()
print(pow(3, 2, 3)) # (3**2)%3 # 0
9、slice() 等同于列表规定步长的取值
lis = ['a', 'b', 'c']
s = slice(1, 4, 1)
print(lis[s]) # print(lis[1:4:1]) # ['b','c']
10、sum() 求和
print(sum(range(100))) # 4950
11、__import__
() 通过字符串导入模块
m = __import__('time')
print(m.time()) # 1556607502.334777
三、面向过程编程
面向 过程 编程
按照 流程(流水线的思想) 码代码
造瓶子
输入原材料(一堆塑料) --> 融化塑料 --> 造瓶身和瓶盖 --> 输出瓶子
一堆变量/参数 --> 函数1(过程1) --> 函数2(过程2) --> 结果
函数3(过程3) --> 函数2(过程2)
上一个过程的输出必定是下一个过程的输入
优点:
- 思路清晰
缺点:
- 上一个过程完蛋了,下一个过程也完蛋
- 功能与功能之间不独立
- 牵一发而动全身,不方便修改/扩展功能,可扩展性差
模块化思想:9个函数分成3大类模块,模块1/模块2/模块3, 以前9个函数互相关联,顶多3个之间互相关联呀.解耦合了(把重复的代码再一次抽离)
例如登录注册功能函数可以做如下解耦合
def input_username_pwd():
username=input('username:')
pwd=input('pwd:')
return username,pwd
def read_file(filename):
with open(filename, 'r', encoding='utf8') as fr:
data = fr.read()
return data
def write_file(filename, data):
with open(filename, 'w', encoding='utf8') as fw:
fw.write(data)
def register():
username, pwd = input_username_pwd()
with open('user_info.txt', 'a', encoding='utf8') as fa:
fa.write(f'{username}:{pwd}|')
def login():
username, pwd = input_username_pwd()
user_info = f'{username}:{pwd}'
data = read_file('user_info.txt')
user_info_list = data.split('|')
if user_info in user_info_list:
print('登录成功')
else:
print('登录失败')
register()
login()