函数方法与面向对象
函数递归
递归,递是递进的意思,归是归来的意思
递归就是用函数在调用一个函数的过程中,又直接或间接地调用了它自身。这样函数会一层一层的递进进去,如果没有条件的话,他就会无限循环。如果有条件的话,当运行到条件中断时,它就会一层一层的回来,直到最初的函数
直接调用
直接调用指的是直接在函数内部调用函数自身
mport sys
# 修改递归层数
sys.setrecursionlimit(10000)
def foo(n):
print('from foo',n)
foo(n+1)
foo(0)
这个函数会递归10000次
间接调用
间接调用指的是不在原函数体内调用函数,而是通过其他方法间接调用函数自身
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
bar()
这段代码会无限循环 from foo from bar 直至到达Python最大递归深度的时候,后面就会循环报错
递归核心
递归本质上还是解决问题的,并不为了让一段代码陷入死循环。所以一般在递进的时候,为了达到一个结果,使问题规模越来越小(不一定要真正达到),可以设置一个条件,能够让最后偶一次函数调用结束
所以,递归更多的是一种思想
下面就用递归来实现几个简单的功能
递归实现从0到100的打印
count = 1 # 2 # 3
def f1():
global count # 下面的count是全局的count
if count > 100:
return
count += 1 # 2 # 3
print(count) # 2 # 3
f1()
f1()
递归实现函数,年龄从16依次加2,输入多少次就打印对应的年龄
def age_func(x): # x的规模在减小 # x = 5 # x =4 # x =3 # x =2 # x = 1 # x = 0
global age
if x == 0:
return age # 终止函数,age=26,这是age_func(0)
return age_func(x - 1) + 2 # 每次加2,向上回归
res = age_func(5)
print(res) # 26
当然简单的函数不用递归也可以,甚至更加的简单
def func(n):
age = 16
age = age + 2 * n
return age
res = func(5)
print(res)
但是当你遇到一些复杂的函数,甚至爬虫的时候,递归就会方便很多
内置方法
掌握
print(abs(-10)) # 绝对值
print(bin(97)) # 二进制
print(hex(97)) # 十六进制
print(oct(97)) #八进制
def func():
pass
print('callable(func):', callable(func)) # 是否能够调用
print('callable([1,]):', callable([1, ]))
print('chr(97):', chr(97))
print(ord('a'))
callable返回true或者false
chr()参考ASCII码表将数字转成对应字符
ord()将字符转换成对应的数字
for ind, value in enumerate([1, 2, 3]):
print(ind, value)
# enumerate()带有索引的迭代
print("eval('1+1'):", eval('1+1')) # 执行括号内部代码
exec('print("1234234234")') # 执行括号内部代码
结果为:
0 1
1 2
2 3
eval('1+1'): 2
1234234234
了解
print(all([1, 2, 3])) # 如果列表内所有元素的bool值都为真则为真
print(any([1, 2, 3])) # 如果列表内只要有一个元素的bool值为真则为真
print(ascii([1, 234])) # 如果为ascii编码则直接返回,否则转二进制
print(bytearray([1, 2, 3])) # 转二进制
print(bytes([1, 2, 3])) # 转二进制
结果为:
True
True
[1, 234]
bytearray(b'\x01\x02\x03')
b'\x01\x02\x03'
import time
print(dir(time)) # 列举time所有功能
print(divmod(10, 3)) # 分栏(除之后数字,余数)
s = frozenset({'skdfjklsdjf', 'sdkfjlk', 'aaaaaa'}) # 不可变集合
print(id(s))
print('globals():', globals()) # 全局
print(hash('234234234')) # 无论你放入什么字符串,永远返回一个固定长度的随机字符串
print(pow(2, 3)) # 2的3次方
print(round(3.55)) # 取整
range(1,2,3)
s = slice(0,2,1)
lis = [1,1,23]
print(lis[s]) # lis[0:2:1]
print(sum([1,2,23])) # 相加
time = __import__('time') # 导入模块的另外一种方式
print(time.time())
面向过程 编程
按照流程(流水线的思想)码代码
流程
一堆变量/参数 --> 函数1(过程1) --> 函数2(过程2) --> 结果
函数3(过程3) --> 函数2(过程2)
上一个过程的输出必定是下一个过程的输入
优缺点
优点:思路清晰
缺点:上一个过程出错了,下一个过程也跟着完蛋
功能与功能之间相互不独立
牵一发而动全身,不方便进行修改,可扩展性差
模块化思想
可以将函数分为好几个模块,模块之间相互关联
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()