函数编程
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
数据存储到硬盘,硬盘只能存储二进制
2进制-十进制-ascii/gbk/utf-8/ unicode
数据往硬盘上存,就要以相应的编码转成二进制后存储
文字->utf-8/gbk->二进制
图片->jpg/png->二进制
音乐->mp3/wav->二进制
视频->mp4/mov->二进制
bytes类型以16进制形式表示,两个16进制数,构成一个bytes,以b来标识
py3文件的默认编码是utf-8
pycharm默认加载文件都是用utf-8编码
with open(“bytes.txt”,“w”,encoding = “utf-8”) as f: 指定编码
f.write(“你好,未来”)
python按你指定的编码来编成2进制
b binary
1.字符存硬盘要变成bytes
2.网络传输,字符要变成bytes
with open("bytes.txt","wb") as f:
f.write("你好,未来".encode("utf-8"))
with open("bytes.txt","rb") as f:
print(f.read())
编码与解码
s.encode(“utf-8”) 以utf-8编码成二进制
s.decode(“utf-8”) 从二进制解码成unicode str
编码转换
把文字从一种编码转成另外一种,从gbk转成utf-8
为什么要进行编码转换?
windows gbk
文件:gbk
linux/mac utf-8
文件:utf-8
gbk—>unicode—>utf-8
unicode:万国码,
跟所有的编码之间有映射关系
dict,list,set
s = {name:alex}
s2 = s 此时s2和s是共享同一份数据的
copy一份新数据
浅copy,只copy第一层
s2 = s.copy()
深copy
s4 = copy.deepcopy(s)
with open("bytes.txt","wb") as f:
f.write("你好,未来".encode("gbk"))
# print(f.read())
with open("bytes.txt","rb") as f:
s = f.read()
print(s)
# 二进制模式rb,wb,ab
#r 文本模式
s_unicode = s.decode("gbk")
s_utf_8 = s_unicode.encode("utf-8")
with open("bytes.txt","wb") as f:
f.write(s_utf_8)
函数是什么
10台
数据库
web
…
define 定义
def 邮件报警(内容):
连接邮箱服务器
发送邮件
关闭连接
while True:
sleep(5)
if cpu > 90%
邮件报警(cpu)
memory
邮件报警(memory)
disk
network
…
为什么用函数
函数怎么用
函数参数
形参
实参
位置参数
按参数的位置把实参和形参对应起来
默认参数
参数在调用时不指定,那默认就是CN
def register(name,age,major = "CS",country = "CN"):
"""
学籍注册程序
:param name: str
:param age: int
:param major: str,Chinese,CS
:param country:JP,CN,US
:return:
"""
info = """
------你的注册信息-----
name:%s
age:%s
major:%s
country:%s
"""%(name,age,major,country)
print(info)
register("张三",22,"CS")
register("李四",26,"cook","JP")
register("Mack",22,"CS")
关键参数
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可(指定了参数名的参数就叫关键参数),但记住一个要求就是,关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后
def register(name,age,major,country = "CN"):
"""
学籍注册程序
:param name: str
:param age: int
:param major: str,Chinese,CS
:param country:JP,CN,US
:return:
"""
info = """
------你的注册信息-----
name:%s
age:%s
major:%s
country:%s
"""%(name,age,major,country)
print(info)
register("alex",major = "中文",age=22)
非固定参数
在定义函数时,不确定后面调用时,会传递多少个参数进来
def register(name,*args,**kwargs):
print(name,args,kwargs)
register("Alex",22,"math",sex ="m")
返回值
全局与局部变量
name = "Alex"
def change():
# name = "金角大王" #局部变量
age = 22
print(name)
print(locals())
print(globals())
return name
change()
print(name)
嵌套
name = "小猿圈"
def change():
name = "小猿圈,自学编程"
def change2():
# global name 如果声明了这句,下面的name改的是最外层的全局变层
name = "小猿圈,自学编程不要钱" #这句注释掉的话,下面name打印的是哪个值?
print("第3层打印", name)
change2() # 调用内层函数
print("第2层打印", name)
change()
print("最外层打印", name)
匿名
res = lambda x,y:x ** y
print(res(2,5))
res = map(lambda x:x ** 2 if x > 10 else x **3,[1,2,3,4,5,6,7])
print(res)
for i in res:
print(i)
高阶函数
str int list dic set tuple
只需满足以下任意一个条件,即是高阶函数
def get_abs(n):
if n < 0 :
n = int(str(n).strip("-"))
return n
def add(x,y,f):
return f(x) + f(y)
res = add(3,-6,get_abs)
print(res)
def left(x,y):
return x * y
def add(x,y,f):
return f(x,y) + f(x,y)
print(add(5,10,left))
用递归实现2分查找的算法,以从列表 a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107] 查找指定的值。
a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107]
def search(start,end,n,list):
mid = (start + end) // 2
if start < end:
if list[mid] > n:
print(f"{n}在左边,第{start}-{mid}之间")
search(start,mid,n,list)
elif list[mid] < n:
print(f"{n}在右边,第{mid+1}-{end}之间")
search(mid + 1,end,n,list)
else:
print(f"找到{n},在列表{a}的第{list.index(n)}个")
else:
print(f"找不到{n}")
search(0,len(a),107,a)
#返回整数的2进制格式
>>> bin(10)
'0b1010'
# 判断一个数据结构是True or False, bool({}) 返回就是False, 因为是空dict
>>> a = [1,2,3]
>>> bool(a)
True
>>> bool(1)
True
>>> bool([])
False
>>> bool({})
False
>>> bool(0)
False
#Return True if bool(x) is True for all values x in the iterable.If the iterable is empty, return True
>>> a
[1, 2, 3]
>>> all(a)
True
>>> a.append(0)
>>> all(a)
False
>>> asset_list = [600,700,1000,None]
>>> all(asset_list)
False
#Return True if bool(x) is True for any x in the iterable.If the iterable is empty, return False
>>> any([{},[],0])
False
>>> any([{},[],0,1])
True
# 把byte变成 bytearray, 可修改的数组
>>> a = "中国".encode("gbk")
>>> a
b'\xd6\xd0\xb9\xfa'
>>> a[0]
214
>>> a[1]
208
>>> bytearray(a)
bytearray(b'\xd6\xd0\xb9\xfa')
>>> b = bytearray(a)
>>> b
bytearray(b'\xd6\xd0\xb9\xfa')
>>> b[1]
208
>>> b[1] = 200
>>> b
bytearray(b'\xd6\xc8\xb9\xfa')
>>> b.decode("gbk")
'秩国'
# bytes(“中国”,”gbk”)
>>> bytes("中国","utf-8")
b'\xe4\xb8\xad\xe5\x9b\xbd'
# 返回一个数字对应的ascii字符 , 比如chr(90)返回ascii里的’Z’
>>> chr(67)
'C'
#求复数,一般人用不到
>>> complex(10,9)
(10+9j)
#返回对象的可调用属性
>>> a
b'\xd6\xd0\xb9\xfa'
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'center', 'count', 'decode', 'endswith', 'expandtabs', 'find', 'fromhex', 'hex', 'index', 'isalnum', 'isalpha', 'isascii', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
#返回除法的商和余数 ,比如divmod(4,2),结果(2, 0)
>>> divmod(4,2)
(2, 0)
#返回列表的索引和元素,比如 d = [“alex”,”jack”],enumerate(d)后,得到(0, ‘alex’) (1, ‘jack’)
>>> a = ["alex","jack"]
>>> enumerate(a)
<enumerate object at 0x00000178F99DAA20>
>>> for i in enumerate(a):print(i)
...
(0, 'alex')
(1, 'jack')
#可以把字符串形式的list,dict,set,tuple,再转换成其原有的数据类型
# names = ["alex","rain","jack"]
#
# f = open("eval.text","w")
# f.write(str(names))
f = open("eval.text","r")
d = eval(f.read())
print(type(d))
print(d[2])
#把字符串格式的代码,进行解义并执行
>>> exec("print('hello world')")
hello world
#对list、dict、set、tuple等可迭代对象进行过滤, filter(lambda x:x>10,[0,1,23,3,4,4,5,6,67,7])过滤出所有大于10的值
>>> filter(lambda x:x>10,[0,1,23,3,4,4,5,6,67,7])
<filter object at 0x00000178F9A02630>
>>> list(filter(lambda x:x>10,[0,1,23,3,4,4,5,6,67,7]))
[23, 67]
#把一个集合变成不可修改的
>>> a
{1, 2, 3}
>>> b = frozenset({1,2,3})
>>> b
frozenset({1, 2, 3})
#打印全局作用域里的值
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': {1, 2, 3}, 'asset_list': [600, 700, 1000, None, 0, {}], 'str': 'alex', 'b': frozenset({1, 2, 3}), 'i': (1, 'jack')}
#判断一个数据结构的类型,比如判断a是不是fronzenset, isinstance(a,frozenset) 返回 True or False
>>> b
frozenset({1, 2, 3})
>>> isinstance(b,frozenset)
True
>>> isinstance(b,set)
False
# map(lambda x:x**2,[1,2,3,43,45,5,6,]) 输出 [1, 4, 9, 1849, 2025, 25, 36]
>>> map(lambda x:x**2,[1,2,3,43,45,5,6,])
<map object at 0x000001C309B9F080>
>>> list(map(lambda x:x**2,[1,2,3,43,45,5,6,]))
[1, 4, 9, 1849, 2025, 25, 36]
# 求最大值
>>> a
{1, 2, 3}
>>> max(a)
3
# 求最小值
>>> min(a)
1
# 返回10进制数的8进制表示
>>> oct(10)
'0o12'
# 返回ascii的字符对应的10进制数 ord(‘a’) 返回97
>>> ord('a')
97
#可以把小数4舍5入成整数 ,round(10.15,1) 得10.2
>>> round(4.15)
4
>>> round(4.15,1)
4.2
#求和
>>> a=[1, 4, 9, 1849, 2025, 25, 36]
>>> sum(a)
3949
#可以把2个或多个列表拼成一个
>>> a=[1, 4, 9, 1849, 2025, 25, 36]
>>> b = ["a","b","c","d"]
>>> list(zip(a,b))
[(1, 'a'), (4, 'b'), (9, 'c'), (1849, 'd')]
名称空间有4种:LEGB
不同变量的作用域不同就是由这个变量所在的名称空间决定的。
作用域即范围
level = 'L0'
n = 22
def func():
level = 'L1'
n = 33
print(locals())
def outer():
n = 44
level = 'L2'
print("outer:",locals(),n)
def inner():
level = 'L3'
print("inner:",locals(),n) #此处打印的n是多少?
inner()
outer()
func()
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
def outer():
name = 'alex'
def inner():
print("在inner里打印外层函数的变量",name)
return inner # 注意这里只是返回inner的内存地址,并未执行
f = outer() # .inner at 0x1027621e0>
f() # 相当于执行的是inner()
关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包
account = {
"is_authenticated":False,# 用户登录了就把这个改成True
"username":"alex", # 假装这是DB里存的用户信息
"password":"abc123" # 假装这是DB里存的用户信息
}
def login(func):
def inner(*args,**kwargs):
if account["is_authenticated"] is False:
username = input("user:")
password = input("pasword:")
if username == account["username"] and password == account["password"]:
print("welcome login....")
account["is_authenticated"] = True
func(*args,**kwargs)
else:
print("wrong username or password!")
else:
print("用户已登录,验证通过...")
func(*args,**kwargs)
return inner
def home():
print("---首页----")
@login
def america():
# login() # 执行前加上验证
print("----欧美专区----")
def japan():
print("----日韩专区----")
@login
def henan(vip_level):
# login() # 执行前加上验证
if vip_level > 3:
print("解锁")
else:
print("----河南专区----")
home()
america()
henan(4)
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a = [i + 1 for i in a]
print(a)
列表生成式
g = (x + 1 for x in range(10))
for i in g:
print(i)
函数生成式
def fib(n):
a = 0
b = 1
count = 0
while count < n:
tmp = a
a = b
b = tmp + b
# print(b)
yield b
count += 1
f = fib(20)
print(f.__next__())
并发编程
#单线程下的多并发效果,线程就是cpu执行的任务单元
#吃包子,c1,c2,c3
#生产者
def consumer(name):
print("消费者%s准备吃包子了"%name)
while True:
baozi = yield
print(f"消费者%s,收到包子编号%s"%(name,baozi))
c1 = consumer("c1")
c2 = consumer("c2")
c3 = consumer("c3")
c1.__next__()
c2.__next__()
c3.__next__()
可以直接作用于for循环的对象统称为可迭代对象:Iterable,可迭代的意思就是可遍历、可循环。
可以使用isinstance()判断一个对象是否是Iterable对象
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
isinstance()判断一个对象是否是Iterator对象:
>>> from collections import Iterator
>>> isinstance([], Iterator)
True
>>> isinstance({}, Iterator)
True
>>> isinstance('abc', Iterator)
True
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance(100, Iterator)
False
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
小结
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
函数编程