第二模块(函数编程(极速版))-第一章-函数编程

系列文章目录


函数编程


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、bytes类型

数据存储到硬盘,硬盘只能存储二进制
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:万国码,
跟所有的编码之间有映射关系

三、深浅copy

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")

五、函数返回值与作用域

返回值

  • 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return语句代表着函数的结束
  • 如果未在函数中指定return,那这个函数的返回值为None

全局与局部变量

  • 在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
  • 全局变量作用域(即有效范围)是整个程序,局部变量作用域是定义该变量的函数。
  • 变量的查找顺序是局部变量>全局变量
  • 当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用;在其它地方全局变量起作用。
  • 在函数里是不能直接修改全局变量的
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
只需满足以下任意一个条件,即是高阶函数

  • 接受一个或多个函数作为输入
  • return 返回另外一个函数
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

  • locals:函数内部的名字空间,一般包括函数的局部变量以及形式参数
  • enclosing function:在嵌套函数中外部函数的名字空间,
    若fun2嵌套在fun1里,对fun2来说,fun1的名字空间就enclosing.
  • globals:当前的模块空间,模块就是一些py文件。也就是说,globals()类似全局变量。
  • builtins: 内置模块空间,也就是内置变量或者内置函数的名字空间,print(dir(builtins))可查看包含的值。

不同变量的作用域不同就是由这个变量所在的名称空间决定的。
作用域即范围

  • 全局范围:全局存活,全局有效
  • 局部范围:临时存活,局部有效
    查看作用域方法 globals(),locals()
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对象。

总结

函数编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值