为了账号安全,请及时绑定邮箱和手机立即绑定
  • 闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:

    # 希望一次返回3个函数,分别计算1x1,2x2,3x3:
    def count():
        fs = []
        for i in range(1, 4):
            def f():
                 return i*i
            fs.append(f)
        return fs
    
    f1, f2, f3 = count()

    你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9(请自己动手验证)。

    原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:

    >>> f1()
    9     # 因为f1现在才计算i*i,但现在i的值已经变为3

    因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。


    查看全部
    0 采集 收起 来源:Python的闭包

    2020-10-08

  • Python内置的 sorted()函数可对list进行排序:

    >>> sorted([36, 5, 12, 9, 21])
    [5, 9, 12, 21, 36]

    可以看到,sorted()函数,默认是由小到大排序列表的元素。

    >>> score = [('Alice', 72), ('Candy', 90), ('Bob', 62)]
    >>> sorted(score)
    [('Alice', 72), ('Bob', 62), ('Candy', 90)]

    当list的每一个元素又是一个容器时,则会以第一个元素来排序,比如在score中,每个元素都是包含名字和成绩的一个tuple,sorted()函数则按名字首字母进行了排序并返回。


    如果需要按照成绩高低进行排序,需要指定排序的字段是成绩,sorted接受key参数,用来指定排序的字段,key的值是一个函数,接受待排序列表的元素作为参数,并返回对应需要排序的字段。因此,sorted()函数也是高阶函数。

    def k(item):
        return item[1] # ==> 按成绩排序,成绩是第二个字段
    
    sorted(score, key=k)

    得到结果:[('Bob', 62), ('Alice', 72), ('Candy', 90)] 。
    如果需要倒序,指定reverse参数即可。

    sorted(score, key=k, reverse=True)

    得到结果:[('Candy', 90), ('Alice', 72), ('Bob', 62)] 。


    查看全部
  • filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,并返回一个迭代器,可以迭代出所有符合条件的元素。
    例如,要从一个list [1, 4, 6, 7, 9, 12, 17]中删除偶数,保留奇数,首先,要编写一个判断奇数的函数:

    def is_odd(x):
        return x % 2 == 1

    然后,利用filter()过滤掉偶数:

    for item in filter(is_odd, [1, 4, 6, 7, 9, 12, 17]):
        print(item)

    结果:1,7,9,17。


    查看全部
  • reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map() 类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

    在python2中,reduce()函数和map()函数一样,可以直接使用,但是在python3中,reduce()函数被收录到functools包内,需要引入functools才可以使用。

    def f(x, y):
        return x + y

    调用 reduce(f, [1, 3, 5, 7, 9]):

    from functools import reduce
    
    def f(x, y):
        return x + y
    
    print(reduce(f, [1,3,5,7,9])) # ==> 25

    reduce()还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为100,计算:

    print(reduce(f, [1, 3, 5, 7, 9], 100)) # ==> 125

    结果将变为125,因为第一轮计算是:

    计算初始值和第一个元素:f(100, 1),结果为101。


    查看全部
  • map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f依次作用在list的每个元素上,map()函数会返回一个迭代器,可以依次迭代得到原来list的元素被函数f处理后的结果。

    >>> map(f, list)

    例如,对于list [1, 2, 3, 4, 5, 6, 7, 8, 9]。
    如果希望把list的每个元素都作平方,就可以利用map()函数。



    我们定义需要传入函数f(x)=x*x,就可以利用map()函数完成这个计算:

    def f(x):
        return x*x
    
    for item in map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]):
        print(item)

    得到结果:

    [1, 4, 9, 10, 25, 36, 49, 64, 81]

    由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。


    查看全部
  • 服务端建立需要四个步骤:新建socket、绑定IP和端口(bind)、监听连接(listen)、接受连接(accept)。

    客户端建立则简单一些,仅需两个步骤:新建socket、连接服务端(connect)。

    当网络连接上以后,客户端和服务端就可以进行数据通信了,套接字通过send()函数发送数据,通过recv()函数接收数据。


    先看服务端的过程,新建一个server.py的文件:

    import socket
    
    server = socket.socket() # 1. 新建socket
    server.bind(('127.0.0.1', 8999)) # 2. 绑定IP和端口(其中127.0.0.1为本机回环IP)
    server.listen(5) # 3. 监听连接
    s, addr = server.accept() # 4. 接受连接
    print('connect addr:{}'.format(addr))
    content =s.recv(1024)
    print(str(content, encoding='utf-8'))  # 接受来自客户端的消息,并编码打印出来
    s.close()

    如上,服务端就编写完毕,接下来是编写客户端,新建一个client.py的文件:

    import socket
    
    client = socket.socket() # 1. 新建socket
    client.connect(('127.0.0.1', 8999)) # 2. 连接服务端(注意,IP和端口要和服务端一致)
    client.send(bytes('Hello World. Hello Socket', encoding='utf-8')) # 发送内容,注意发送的是字节字符串。
    client.close()

    接着在一个终端先运行服务端:

    python server.py

    然后再在另外一个终端运行客户端:

    python client.py

    在服务端的终端,将会输出以下信息:

    connect addr:('127.0.0.1', 50382)
    b'Hello World. Hello Socket'


    查看全部
  • 为了正确关闭文件,需要考虑各种异常情况,这是非常麻烦的一件事,Python提供with关键字,可以免除这类后顾之忧。
    with关键字对资源进行访问的场合,会确保不管在使用过程中是否发生异常,都会执行必要的“清理”的操作,释放资源,比如文件使用后自动关闭等等。
    with的使用方法如下:

    with open('test.txt', 'r') as f:
        content = f.readlines()
        for line in content:
            print(line)

    当文件使用结束后,不需要显式的调用f.close()关闭文件。


    查看全部
  • Python提供文件追加内容的打开模式,可以往文件尾部添加内容,又不清空文件原有的内容。

    模式

    描述

    a

    打开一个文件并追加内容,会往文件尾部添加内容

    ab

    以二进制格式打开一个文件并追加内容,会往文件尾部添加内容

    a+

    打开一个文件并使用追加进行读写

     

    f = open('test.txt', 'a')
    f.write('Hello Everyone\n')
    f.close()

    使用a的打开方式打开文件,文件游标默认是在文件的尾部,因此,可以便捷的往文件尾部添加内容,除此以外,文件对象还提供seek()方法,可以移动文件的游标位置,它接受一个参数,表示文件的位置,0:文件首部,1:当前位置,2:文件尾部,通过seek()可以把文件游标移动到文件首部但不删除文件的内容。

    f = open('test.txt', 'a+')
    content = f.readlines()
    print(content) # ==> []
    f.seek(0)
    content = f.readlines()
    print(content) # ==> ['Hello World\n', 'Hello Python\n', 'Hello Imooc\n']

    第一次print(content)的时候,由于文件游标在文件的尾部,所以readlines()读取不到任何数据,打印了空的结果,第二次print(content)的时候,由于通过seek(0),文件游标移动到了文件的首部,因此readlines()就返回了文件所有的内容。


    查看全部
  •  字符串反转可以使用切片实现: reverse = str_[::-1]

    3. 换行符是'\n',字符串反转的时候,换行符也会翻转


    查看全部
  • f = open('test.txt', 'w')

    写入若干字符

    文件对象提供write方法向文件内写入若干字符,它接受一个字符串参数,表示需要写入的字符串。

    f = open('test.txt', 'w')
    f.write('Hello World\n')
    f.close()

    写入若干行

    文件对象提供writelines()方法向文件内容写入多行数据,它接受一个列表,表示需要写入的字符串列表。

    lines = ['Hello World\n', 'Hello Python\n', 'Hello Imooc\n']
    f = open('test.txt', 'w')
    
    f.writelines(lines)
    f.close()


    查看全部
  • 读取若干字符

    文件对象提供read()方法,可以读取文件中的若干个字符,它提供一个参数size,可以指定读取字符的数量。

    s = f.read(5)
    print(s) # ==> Hello

    当read()之后,访问文件的游标就会移动到第六个字符前面,此时,继续read,将得到Hello后面的结果。

    s = f.read(6)
    print(s) # ==> ' World'


    读取一行

    文件对象提供readline()方法,和read()方法类似,可以读取文件中的若干个字符,它也提供一个参数size,可以指定读取字符的数量,不过和read()方法不同的是,readline()方法遇到一行结束的时候,就会返回。

    f.close()
    f = open('test.txt', 'r') # 重新打开文件
    s = f.readline(20)
    print(s)  # ==> 'Hello World.\n'

    可以看到,打印的内容并没有20个字符,readline最多返回一行的所有字符。


    读取多行

    文件对象提供readlines()方法,可以读取多行字符,返回一个列表。它提供一个hint参数,表示指定读取的行数,没有指定则默认以列表的形式返回文件所有的字符串。

    f.close()
    f.open('test.txt', 'r')
    s = f.readlines()
    print(s) # ==> ['Hello World.\n', 'Hello Python.\n', 'Hello Imooc.\n']


    查看全部
  • 除了文本以外,还有大量的非文本文件,比如图片、压缩文件、视频文件、音乐文件等等,这种文件统称为二进制文件,在Python中打开二进制文件,需要不同的打开模式。

    b

    二进制模式,打开二进制文件

    wb

    以二进制格式只写模式打开一个文件,会清除原有的内容

    ab

    以二进制格式打开一个文件并追加内容,会往文件尾部添加内容

    rb

    以二进制格式只读模式打开一个文件

    f = open('test.jpg', 'rb')
    f.close()


    查看全部
  • 常用的打开模式如下:

    模式

    描述

    t

    文本模式(默认)

    x

    写模式,新建一个文件

    b

    二进制模式,打开二进制文件

    +

    更新一个文件(可读可写)

    r

    以只读模式打开一个文件

    rb

    以二进制格式只读模式打开一个文件

    w

    打开一个文件进行写入,如果文件内容已存在,会清除原有的内容

    wb

    以二进制格式只写模式打开一个文件,会清除原有的内容

    a

    打开一个文件并追加内容,会往文件尾部添加内容

    ab

    以二进制格式打开一个文件并追加内容,会往文件尾部添加内容

    w+

    打开一个文件进行读写,如果文件内容已存在,会清除原有的内容

    a+

    打开一个文件并使用追加进行读写

    注意,为了安全操作文件,文件使用完毕后,需要使用close()函数正确关闭。
    在当前目录下新建一个test.txt文件,并新建一个main.py,此时文件目录如下:

    |-- test.txt
    +-- main.py

     

    f = open('test.txt', 'r') # 打开test.txt文件
    type(f) # 打印f的类型(<class '_io.TextIOWrapper'>)
    f.close() # 关闭文件


    查看全部
  • 缩进错了就完蛋了

    查看全部
  • 如果需要导入自定义模块,则需要了解Python导入模块搜索的路径。
    通过sys模块,可以知道导入模块的路径。

    >>> import sys
    >>> sys.path
    ['', '/data/miniconda3/lib/python3.8', '/data/miniconda3/lib/python3.8/site-packages']

    它返回的是一个列表,表示的是在搜索Python模块时,会搜索的路径,在示例中,返回了四个路径。我们分析一些关键路径:
    第一个路径是'',它是一个空字符串,表达的是当前路径的意思。
    第二个路径是/data/miniconda3/lib/python3.8,它是Python默认模块的存放的路径,在这个路径下,可以发现有os、sys等模块的代码。
    第三个路径是/data/miniconda3/lib/python3.8/site-packages,它是第三方模块代码的存放路径,在这个路径下,存放的是需要安装的第三方模块。



    那如何使用我们前面定义的tools.py模块呢?
    我们在tools.py同级目录,创建main.py文件:

    # main.py
    
    import tools # 导入模块
    
    tools.say_hello() # 调用模块里面的say_hello()函数
    tools.say_goodbye() # 调用模块里面的say_goodbye()函数

    就可以运行了。


    查看全部

举报

0/150
提交
取消
课程须知
本课程是Python入门的后续课程 1、掌握Python编程的基础知识 2、掌握Python函数的编写 3、对面向对象编程有所了解更佳
老师告诉你能学到什么?
1、什么是函数式编程 2、Python的函数式编程特点 3、Python的模块 4、Python面向对象编程 5、Python强大的定制类

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!