习题二十 会话

# 从sys包中导入argv模块
from sys import argv# 将argv解包
script, input_file = argv# 定义print_all()函数,该函数接收一个参数
def print_all(f):# 读取给定文件的内容,并将其打印出来print(f.read())# 定义rewind()函数,该函数接收一个参数
def rewind(f):# 将光标移动到给定文件的开头位置f.seek(0)# 定义print_a_line()函数,该函数接收两个参数
def print_a_line(line_count, f):# 打印line_count变量,仅读取给定文件的一行内容print(line_count, f.readline())# 打开input_file文件,并将其打开的文件对象赋值给current_file
current_file = open(input_file)print("First let's print the whole file:\n")# 运行函数print_all(),将current_file作为参数传递给该函数
print_all(current_file)print("Now let's rewind, kind of like a tape.")# 运行函数rewind(),将current_file作为参数传递给该函数
rewind(current_file)print("Let's print three lines:")# 定义current_line,赋值为1
current_line = 1
# 运行函数print_a_line(),将current_line,current_file分别作为line_count,f的参数传递给该函数
print_a_line(current_line, current_file)# 将current_line的值+1重新赋给current_line
current_line = current_line + 1
# 运行函数print_a_line(),将current_line,current_file分别作为line_count,f的参数传递给该函数
print_a_line(current_line, current_file)# 将current_line的值+1重新赋给current_line
current_line = current_line + 1
# 运行函数print_a_line(),将current_line,current_file分别作为line_count,f的参数传递给该函数
print_a_line(current_line, current_file)
PS D:\pythonp> python ex20.py test20.txt
First let's print the whole file:This is line 1.
This is line 2.
This is line 3.Now let's rewind, kind of like a tape.
Let's print three lines:
1 This is line 1.2 This is line 2.3 This is line 3.

.readline():只读取文本文件的一行

  • readline()里边的代码会扫描文件的每一个字节,直到找到一个\n为止,然后它停止读取文件,并且返回此前发现的文件内容。
  • 文件会记录每次调用readline()后的读取位置,这样它就可以在下次被调用时读取接下来的一行了。
  1. 为每一行加上注释,以便理解这一行的作用。

  2. 每次print_a_line运行时,你都传递了一个叫current_line的变量。每次调用函数时,打印出current_line的值,跟踪一下它在print_a_line中是怎样变成line_count的。

    其实current_line的具体数值跟line_count没有关系,按行输出是依靠readline()函数只读取一行的性质。根据这一性质,将current_line的初始值设为1,然后令其每运行一次递增1,使其与line_count相匹配。

    若将初始值改成别的值,就会出现不匹配的现象如下

    PS D:\pythonp>  python ex20.py test20.txt
    First let's print the whole file:This is line 1.
    This is line 2.
    This is line 3.Now let's rewind, kind of like a tape.
    Let's print three lines:
    2 This is line 1.3 This is line 2.4 This is line 3.

    若将每运行一次+1去掉,就会出现重复数字。

    PS D:\pythonp> python ex20.py test20.txt
    First let's print the whole file:This is line 1.
    This is line 2.
    This is line 3.Now let's rewind, kind of like a tape.
    Let's print three lines:
    1 This is line 1.1 This is line 2.1 This is line 3.
  3. 找出脚本中每一个用到函数的地方。检査def一行,确认参数没有用错。

    没有用错~

  4. 上网研究一下file中的seek函数是做什么用的。试着运行 pydoc file,看看能不能学到更多。然后试一下 pydoc file.seek,看看seek是做什么用的。

seek()函数

  • 概述
    seek() 方法用于移动文件读取指针到指定位置。

  • 语法
    seek() 方法语法如下:

fileObject.seek(offset[, whence])

  • 参数

    • offset – 开始的偏移量,也就是代表需要移动偏移的字节数
    • whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
  • 返回值
    如果操作成功,则返回新的文件位置,如果操作失败,则函数返回 -1。

  1. 研究一下+=这个简写操作符的作用。重写这个脚本,在里边用一下这个操作符

+=

x += y 等同于 x = x + y

习题21 函数可以返回某些东西

# 定义add函数:输出给定的两个参数值相加得到的结果
def add(a, b):print(f"ADDING {a} + {b}")return a + b# # 定义subtract函数:输出给定的两个参数值相减得到的结果
def subtract(a, b):print(f"SUBTRACTING {a} + {b}")return a - b# 定义multipl函数:输出给定的两个参数值相乘得到的结果
def multiply(a, b):print(f"MULTIPLYING {a} * {b}")return a * b# 定义divide函数:输出给定的两个参数值相除得到的结果
def divide(a, b):print(f"DIVIDING {a} / {b}")return a / b# 输出说明字符串
print("Let's do some math with just functions!")# 调用add,subtract,multiply,divide函数分别为age,height,weight,iq变量赋值
age = add(30, 5)
height = subtract(78, 4)
weight = multiply(90, 2)
iq = divide(100, 2)# 输出说明字符串
print(f"age: {age}, height: {height}, weight: {weight}, iq: {iq}")# a puzzle for the extra credit, type it in anyway.
print("Here is a puzzle.")# 给what变量赋值,其公式实际上是what = age + height - weight *(iq / 2)
what = add(age, subtract(height, multiply(weight, divide(iq, 2))))# 输出结果
print("That becomes: ", what, "Can you do it by hand?")
PS D:\pythonp> python ex21.py
Let's do some math with just functions!
ADDING 30 + 5
SUBTRACTING 78 + 4
MULTIPLYING 90 * 2
DIVIDING 100 / 2
age: 35, height: 74, weight: 180, iq: 50.0
Here is a puzzle.
DIVIDING 50.0 / 2
MULTIPLYING 180 * 25.0
SUBTRACTING 74 + 4500.0
ADDING 35 + -4426.0
That becomes:  -4391.0 Can you do it by hand?
  1. 如果你不是很确定return的功能,试着自己写几个函数,让它们返回一些值。你可以将任何可以放在=右边的东西作为一个函数的返回值。

  2. 这个脚本的结尾是一个谜题。我将一个函数的返回值用作了另外一个函数的参数。我将它们链接到了一起,以便我能用函数创建一个公式。这样可能有些难度,不过运行下你就知道结果了。接下来,你需要试试看能不能找出正常的公式来重新创建同样一组运算。

    如下代码得出同样的结果

what1 = divide(iq, 2)
what2 = multiply(weight, what1)
what3 = subtract(height, what2)
what_one = add(age, what3)
print(what_one)
DIVIDING 50.0 / 2
MULTIPLYING 180 * 25.0
SUBTRACTING 74 + 4500.0
ADDING 35 + -4426.0
-4391.0
  1. 一旦你有了解决这个谜题的公式,试着修改一下函数里的某些部分,然后看一下会发生什么情况。你可以有目的地修改它,让它输出另外一个值。
what1 = divide(iq, 2)
# 此处令传递给multiply的第一个参数变为weight+5
what2 = multiply(weight + 5, what1)
what3 = subtract(height, what2)
what_one = add(age, what3)
print(what_one)
DIVIDING 50.0 / 2
# 可以看到此处第一个参数由180变为185,并影响了后续计算
MULTIPLYING 185 * 25.0
SUBTRACTING 74 + 4625.0
ADDING 35 + -4551.0
-4516.0
  1. 颠倒过来做一次。写一个简单的公式,一样使用函数来计算它。

24+34/100-1023

# 24+34/100-1023# 定义add函数,输出提示性字符串并返回两变量相加所得的值
def add(a, b):print(f"ADDING {a} + {b}")return a + b# 定义subtract函数:输出提示性字符串并返回两变量相减所得的值
def subtract(a, b):print(f"SUBTRACTING {a} - {b}")return a - b# 定义divide函数:输出给定的两个参数值相除得到的结果
def divide(a, b):print(f"DIVIDING {a} / {b}")return a / b# 将24+34/100-1023的结果赋值给number
number = add(4, subtract(divide(34, 100), 1023))# 输出number的值,即公式的结果
print(number)
IVIDING 34 / 100
SUBTRACTING 0.34 - 1023
ADDING 4 + -1022.66
-1018.66

return

  • return是函数传回值的一个基本方式
  • return 语句就是将结果返回到调用的地方,并把程序的控制权一起返回
  • 程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return
  • 退出函数,选择性地向调用方返回一个表达式
  • 不带参数值的return语句返回None

实例

# 可写函数说明
def sum( arg1, arg2 ):   # 返回2个参数的和.   total = arg1 + arg2   print "函数内 : ", total   return total  # 调用sum函数
total = sum( 10, 20 )
函数内 :  30
  • 要返回两个数值,写成一行即可
def a(x,y):if x==y:return x,yprint a(3,3)<br><br>>>> 3,3
  • 但是也并不意味着一个函数体中只能有一个return 语句
def test_return(x):if x > 0:return xelse:return 0
  • 函数没有 return,默认 return一个 None 对象。

  • 递归函数中没有return 的情况:

def gcd(a,b):if a%b==0:return belse:gcd(b,a%b)

分析:else 中没有 return 就没有出口,这个程序是自己内部运行,程序没有返回值,

return 和 print 的区别:

x = 1
y = 2
def add (x, y):z = x + yreturn z
print (add(x,y)x = 1
y = 2
def add (x, y):z = x + yprint z
print (add(x,y))
  • 在交互模式下,return的结果会自动打印出来,而作为脚本单独运行时则需要print函数才能显示。

  • 默认情况下,遇见 return 函数就会返回给调用者,但是 try,finally情况除外:

def func():  try:  print 98  return 'ok' #函数得到了一个返回值  finally: #finally语句块中的语句依然会执行  print 98  print fun()

输出:

98
98
ok
  • 函数作为返回值返回:
def lazy_sum(*args):def sum():x=0for n in args:x=x+nreturn xreturn sumlazy_sum(1,2,3,4,5,6,7,8,9) #这时候lazy_sum 并没有执行,而是返回一个指向求和的函数的函数名sum 的内存地址。
f=lazy_sum(1,2,3,4,5,6,7,8,9)
print(type(f))
print(f())  # 调用f()函数,才真正调用了 sum 函数进行求和,

这其实就是闭包。

  • 返回一个函数列表:
def count():fs = []for i in range(1,4):def f():return i*ifs.append(f)return fsf1, f2, f3 = count()
print(f1())
print(f2())
print(f3())

输出:

9
9
9
  • 执行过程:

    • 当i=1, 执行for循环, 结果返回函数f的函数地址,存在列表fs中的第一个位置上。
    • 当i=2, 由于fs列表中第一个元素所指的函数中的i是count函数的局部变量,i也指向了2;然后执行for循环, 结果返回函数f的函数地址,存在列表fs中的第二个位置上。
    • 当i=3, 同理,在fs列表第一个和第二个元素所指的函数中的i变量指向了3; 然后执行for循环, 结果返回函数f的函数地址,存在列表fs中的第三个位置上。
      所以在调用f1()的时候,函数中的i是指向3的:

f1():
return 3*3
同理f2(), f3()结果都为9
闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。即包在里面的函数(本例为f()),不要引用外部函数(本例为count())的任何循环变量

如果一定要引入循环变量,方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

def count():fs=[]for i in range(1,4):def f(j):def g():return j*jreturn gfs.append(f(i))return fsf1,f2,f3=count()
print(f1())
print(f2())
print(f3())

笨办法学python3 学习笔记 习题20-21相关推荐

  1. 笨办法学python3 学习笔记 习题43 基本的面向对象分析和设计

    习题43 基本的面向对象分析和设计 通过面向对象编程(OOP)构建一些东西的流程(常用)(自顶向下) 把要解决的问题写下来,或者画出来. 将第一条中的关键概念提取出来并加以研究. 创建一个类层次结构和 ...

  2. 笨办法学python3 学习笔记 习题42 对象、类及从属关系

    类中的self 在类中定义函数时,第一参数永远是类的本身实例变量self,并且调用时,不用传递该参数.

  3. 笨办法学python__学习笔记

    笨办法学python –20190307 之前开始学习python过多次,每次都以失败告终.其实我有计算机语言的基础,高中时在步步高词典上是basic写过小程序,大学时自学C.不过学C的时候不得要领, ...

  4. 笨办法学Python——学习笔记1

        最近想学gtk,但是gtk在window上编译和运行挺慢的,于是搜索了一下发现了pygtk.在前几天 把环境都配好了,现在想同时学gtk和pygtk,但Python没学过,找到了<笨办法 ...

  5. 《笨办法学》 学习笔记一

    习题1-5 总结: 1.使用Terminal 创建一个目录: 在Terminal中 输入 mkdir mystuff(目录名可随意设置). 使用Terminal 进入这个目录:继续输入 cd myst ...

  6. 读书笔记 笨办法学python3

    读后评价 <笨办法学Python3>是一本适合Python3的初学者实用性书籍,以52个练习题为章节讲述了Python3的基础知识,包括基本语法.控制流程.列表.字典.元组.面向对象(类, ...

  7. 《笨办法学python3》再笨的人都能学会python,附PDF,拿走不谢

    <笨办法学python3>这本书的最终目标是让你起步python编程,虽然说是用"笨办法"学习写程序,但是其实并不是这样的. 所谓的"笨办法"就是指 ...

  8. 笨办法学python 粗略笔记(learn python the hard way)

    笨办法学python 粗略笔记(learn python the hard way) 标签(空格分隔): python # _*_ coding: utf_8 _*_ ''' ### ex1 prin ...

  9. [IT学习]Learn Python the Hard Way (Using Python 3)笨办法学Python3版本

    黑客余弦先生在知道创宇的知道创宇研发技能表v3.1中提到了入门Python的一本好书<Learn Python the Hard Way(英文版链接)>.其中的代码全部是2.7版本. 如果 ...

最新文章

  1. python processpoolexector 释放内存_关于python:如何在multiprocessing.queue中从Process中释放内存?...
  2. APM之基于事件的异步模式(EAP)-2
  3. Spark任务调度流程及调度策略分析
  4. 微信网页授权功能来获取用户信息(昵称或头像)之php实现
  5. 爱我别走:产品大改版时,如何避免用户流失?
  6. JavaScript 中的常用12种循环遍历(数组或对象)的方法
  7. ceph学习之pool
  8. asp.net core监控—引入Prometheus(四)
  9. android xml 预览,解决Android studio xml界面无法预览问题
  10. uniapp-登录界面风格-001
  11. Excel 两列合并为一列中间加空格
  12. 程序员的奋斗史(三十七)——大学断代史(一)——开篇
  13. sendgrid_使用SendGrid处理传入的电子邮件
  14. 北京CBD核心区有哪些值得加入的科技公司
  15. 【送谷歌定制礼品】一起寻找最初的写作热忱 即刻动笔!
  16. 以太坊开发(一)——Truffle和Ganache
  17. python中turtle的用法及实例--你的唐僧哥哥
  18. 谷歌地球也疯狂 五款Google Earth游戏
  19. 串扰几种常见措施的效果及差异
  20. win10 自启动设置无效

热门文章

  1. 知乎高赞:35岁失业的程序员,最后都去了哪儿?是在路边摊炒粉和做烤鸭?...
  2. 47 On Interpersonal Relationship 关于人际关系
  3. UWP控件与DataBind
  4. 微信小程序1-配置文件
  5. 【数据结构】平衡二叉树的插入、删除
  6. android电话拦截软件下载,骚扰电话拦截器
  7. 【软件网每日新闻播报│第9-25期】
  8. Golang单元测试指引
  9. android 驾考宝典,驾考宝典安卓版
  10. linux从光盘中安装php,Linux_Vfloppy通过CD光盘安装Linux到硬盘运行,光盘版的linux系统,可以证我 - phpStudy...