Python教程网
--左手Python,右手AI!

牛逼!Python函数和文件操作(长文系列第三篇)

牛逼!Python函数和文件操作(长文系列第三篇)

原创 教授 程序员教授 8月4日
收录于话题 #Python系列文章

系列第三篇来说一下函数和文件。函数在编程中是一个很重要的角色,我们可以将若干个语句组合形成一个函数,它可以接受传入参数,并在内部进行相关计算后产生输出,将语句封装成函数是为了避免重复使用几个语句造成代码冗杂,让代码更简洁可观性更强。
文件的操作主要是介绍一些关于文件的读取及写入的方法,以及每个方法的不同点和需要注意的事项,最后会介绍一下利用pickle模块存储复杂数据的方式。


函数

函数主要包括两个方面:

  1. 内置函数
  2. 自定义函数

内置函数就是python自带的一些函数,我们只需要给函数传入相关参数就可以进行调用,print就是最基础、最典型的一个内置函数;而自定义函数是需要我们自己按照需求,封装若干个语句形成一个新的函数。

自定义函数

1.创建函数
下面通过自定义一个计算长方体体积的函数来介绍一些属性词:

In [1]: def  vol(length,width,height):
   ...:     volume = length*width*height
   ...:     return volume

上面三行代码中你需要了解:

def:定义函数的关键字
length,width,height:函数的形参
return:函数的返回值

2.调用函数

建好一个自定义函数后,可以通过函数名(实参)的方式调用函数:

In [2]: vol(2,2,3)
Out[2]: 12
    ```
在传入参数时需要注意的是,实参与形参必须完全对应,比如位置、个数等等,否则会出现报错。
```python
In [4]: vol(2,2)
TypeError: vol() missing 1 required positional argument: 'height'
    ```
如果想改变传参顺序,那么你需要指定为哪一个形参传值:
```python
In [8]: vol(width=3,length=4,height=5)
Out[8]: 60

</code></pre>

3.函数默认值

函数的形参还可以指定默认值,假如我们将上面的vol函数中height参数默认值设为2:

<pre><code class="language-python ">In [6]: def  vol(length,width,height=2):
   ...:     volume = length*width*height
   ...:     return volume
   ...:
In [7]: vol(2,2)
Out[7]: 8
</code></pre>

这时只向vol函数中传入两个实参,可以发现没有报错,并且得到返回值为8。也就是说如果一个形参有默认值,而调用函数时没有为这个形参传值,那么这个参数就取默认值。

4.收集函数(可变函数)

对于一个函数的形参我们也可以将其设置为可以变化的:

<pre><code class="language-python ">In [9]: def test(*params):
   ...:     print('参数的长度为%d'%len(params))
   ...:     print('第三个参数为%s'%params[2])
   ...:
In [10]: test(1,2,'mao',3.14,'pp')
</code></pre>

参数的长度为5
第三个参数为mao
这里需要将形参用*标识,然后在调用参数的时候可以传入若干个实参。

5.全局与局部

在函数中定义的常量被称为局部变量,也就是仅限在这个函数中可以调用,不接受在函数之外使用:

<pre><code class="language-python ">In [12]: def test(a,b):
    ...:     c = 2
    ...:     return a*b*c

In [13]: test(2,2)
Out[13]: 8
In [14]: print(c)
NameError: name 'c' is not defined
</code></pre>

6.匿名函数lambda

如果一个函数内部的语句不是很复杂,代码量很少,我们就可以利用匿名函数,比如上面计算体积的函数:

<pre><code class="language-python ">In [20]: vol = lambda a,b,c:a*b*c

In [21]: vol(2,2,3)
Out[21]: 12
</code></pre>

lambda表达式常常嵌套的语句中,结合相关函数使用会很简便,后面会给出例子。

7.内嵌函数

在定义函数时还支持几个函数嵌套,但用的时候需要注意逻辑关系:

<pre><code class="language-python ">In [24]: def fun1(a):
    ...:     b = 2
    ...:     def fun2():
    ...:         return a*b
    ...:     return fun2()
    ...:

In [25]: fun1(4)
Out[25]: 8
</code></pre>

<h3>常用内置函数</h3>

内置函数前两篇文章就有涉及过,比如常用的len、sorted、reversed、sum等等,除此之外再介绍几个比较基础的内置函数。

1.max和min

<pre><code class="language-python ">求一个序列中最大值和最小值:

In [28]: min(1,2,3)
Out[28]: 1

In [29]: max(1,2,3)
Out[29]: 3

</code></pre>

2.abs

<pre><code class="language-python ">求一个数的绝对值:

In [31]: abs(-1)
Out[31]: 1


</code></pre>

3.round

<pre><code class="language-python ">四舍五入保留小数点后几位:

In [32]: round(3.555,2)
Out[32]: 3.56


</code></pre>

4.pow

<pre><code class="language-python ">计算一个数的幂次方,或者再取余:

In [33]: pow(2,3)#2*2*2
Out[33]: 8

In [34]: pow(2,3,3)#(2*2*2)%3
Out[34]: 2


</code></pre>

5.divmod

<pre><code class="language-python ">计算一个数的商和余数:

In [36]: divmod(10,3)
Out[36]: (3, 1)

    ```
6.help
```python
用来查询一个函数的帮助文档:

In [37]: help(abs)
Help on built-in function abs in module builtins:

abs(x, /)
    Return the absolute value of the argument.

</code></pre>

7.filter

filter()函数接收两个参数,第一个参数可以是一个函数或者None,第二个参数是序列。作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉序列中为False的元素,留下为True的元素,可以结合lambda表达式使用:

<pre><code class="language-python ">In [38]: list(filter(lambda x:x%2,range(10)))
Out[38]: [1, 3, 5, 7, 9]
</code></pre>

8.map

map()函数接收两个参数,一个是函数,一个是序列。作用是将函数应用于序列中每一个元素上,同样可以结合lambda表达式使用:

<pre><code class="language-python ">In [42]: list(map(lambda x: x*2,range(10)))
Out[42]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
</code></pre>

<hr />

<img src="https://www.xiaozhan95.com/wp-content/uploads/2020/09/1.png" alt="" />

<h2>文件</h2>

关于文件读写操作,open()函数是一定遇到的,如果文件已经存在则会打开文件,若不存在则会创建一个文件,通常的用法需要两个参数:open(filename,mode)。

第一个参数就是文件名字,第二个参数就指定文件将会被如何使用,可选模式常用的有以下几种:

<em>'r':以只读的方式打开文件(默认)
'w':以写入模式打开文件,会覆盖已存在的文件
'a':以写入模式打开文件,如果文件存在,则在末尾追加写入
'b':以二进制模式打开文件,进而会有rb、wb等模式组合</em>

1.read()方法读取

read()方法可传入一个参数size,也就是读取内容的长度。size是一个可选参数,如果不传入或者传入一个负数,那么会读取文件全部内容:

<pre><code class="language-python "><br />In [52]: fb = open('E:/Python基础/test.txt','r')

In [53]: fb.read(10)
Out[53]: 'nai\nniatan'

In [54]: fb.read()
Out[54]: 'g\nnaitangmao'

In [55]: fb.read()
Out[55]: ''
</code></pre>

需要注意的有三点:

<ol>
<li>原文件中换行的地方在读取时以换行符'\n'表示,并且也占有一个单位长度</li>
<li>已经被读取的内容不能被重复读取</li>
<li>如果读取内容返回为空字符串,表示已经到了文件末尾</li>
</ol>

2.readline()方法

readline()方法是从文件中读取单独一行,并且在这一行数据的末尾处会有一个换行符'\n',如果其中一行没有数据,则会只返回一个'\n',同样当返回空字符串时表示到达文件末尾。

<pre><code class="language-python ">In [59]: fb1 = open('E:/Python基础/test.txt','r')

In [60]: fb1.readline()
Out[60]: 'nai\n'
</code></pre>

3.readlines()方法

readlines()方法也是用来读取全部文件,与read()不同之处在于前者是按行读取,并且最后返回的是一个列表,每一行数据作为一个列表元素:

<pre><code class="language-python ">In [72]: fb3 = open('E:/Python基础/test.txt','r')

In [73]: fb3.readlines()
Out[73]: ['nai\n', 'niatang\n', 'naitangmao']
</code></pre>

4.遍历文件对象读取

这种方式读取出的内容看起来会比较规范一些:

<pre><code class="language-python ">In [81]: for i in fb4:
    ...:     print(i,end = '')
    ...:
nai
niatang
naitangmao
</code></pre>

5.文件的写入

在进行写入操作的时候,我们需要注意的两个点:

写入的数据如果是非字符串内容,需要转换为字符串
写入的方式要注意是覆盖还是追加

<pre><code class="language-python ">In [85]: fb5 = open('E:/Python基础/test1.txt','w')

In [89]: list1 = [1,2]
In [91]: fb5.write(str(list1))
Out[91]: 6

#用write写入后会返回写入字符串的长度
    ```


6.文件关闭

切记切记切记!如果你用open()的方式打开一个文件,在操作完成之后一定要用close()方法关闭文件。
```python
In [92]: fb5.close()
    ```

7.with方式

如果你感觉自己的记性不好,总是忘记用close()方法关闭文件,那么就要习惯利用with处理文件对象,它可以在文件用完之后自动关闭文件。
```python
In [93]: with open('E:/Python基础/test.txt','r') as fb:
    ...:     data = fb.read()

In [95]: fb.closed
Out[95]: True

8.pickle

上面说了将一个非字符串写入文件是不允许的,如果有没有办法保存一份字典或者列表形式的数据呢?pickle模块就可以实现这种序列化的存储与读取:

In [96]: import pickle
In [97]: list1 = ['nai','tang','mao',1,2,3]

In [98]: pic_f = open('E:/Python基础/list.pkl','wb')
In [99]: pickle.dump(list1,pic_f)
In [100]: pic_f.close()

dump()方法接收两个参数,第一个是要存储的内容,第二个是存储的文件对象,操作之后也需要用close()关闭文件对象,存储之后可以利用load()方法加载文件中的内容。

In [102]: pic_f = open('E:/Python基础/list.pkl','rb')
In [103]: list2 = pickle.load(pic_f)

In [104]: list2
Out[104]: ['nai', 'tang', 'mao', 1, 2, 3]
In [105]: pic_f.close()

利用pickle在存储或者读取的时候要注意以二进制的形式操作文件对象,也就是’wb’和’rb’,pickle很适合用来存储数据类型比较复杂并且数据量又很大的数据。


往期推介:

第一篇传送门
第二篇传送门

赞(10)
未经允许不得转载:Python教程网 » 牛逼!Python函数和文件操作(长文系列第三篇)
分享到: 更多 (0)

评论 2

  1. #1

    I happen to be writing to make you know what a beneficial discovery my child gained browsing your webblog. She came to understand a lot of details, most notably how it is like to have a very effective coaching heart to have folks with ease learn about specific hard to do matters. You actually exceeded our own expectations. Many thanks for producing these interesting, trustworthy, edifying and cool thoughts on your topic to Emily.

    匿名1个月前 (12-24)回复
  2. #2

    hello guos 9128738514

    匿名3周前 (01-04)回复