返回顶部
首页 > 资讯 > 后端开发 > Python >《Python基础教程》第六章--读书
  • 237
分享到

《Python基础教程》第六章--读书

第六章基础教程Python 2023-01-31 08:01:50 237人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

本章会介绍如何将语句组织成函数。还会详细介绍参数(parameter)和作用域(scope)的概念,以及递归的概念及其在程序中的用途。 懒惰即美德 斐波那契数列:任何一个数都是前两个数之和的数字序列。 创建函数 内建的callable函

本章会介绍如何将语句组织成函数。还会详细介绍参数(parameter)和作用域(scope)的概念,以及递归的概念及其在程序中的用途。

懒惰即美德

斐波那契数列:任何一个数都是前两个数之和的数字序列。

创建函数

内建的callable函数可以用来判断函数是否可调用:

>>>import math
>>>x = 1
>>>y = math.sqrt
>>>callable(x)
False
>>>callable(y)
True

注:函数callablepython3.0中不再可用,需要使用表达式hasattr(func,__call__)代替。
创建斐波那契数列列表的函数:

def fibs(num):
    result=[0,1]
    for i in range(num-2):
        result.append(result[-2]+result[-1])
    return result
fibs(8)

文档化函数

  • 如果想要给函数写文档,让其他使用函数人能理解的话,可以加入注释(以#开头)。

  • 另外一个方式就是直接写上字符串。这类字符串在其他地方可能会非常有用,比如在def语句后面。

如果在函数的开头写下字符串,他就会作为函数的一部分进行存储,这成为文档字符串。

def square(x):
    'Calculate the square of the number'
    return x*x
>>>square.__doc__
'Calculate the square of the number'

注:__DOC__是函数属性。第七章会介绍更多关于属性的知识。属性名中的双下划线是个特殊属性。这类特殊和“魔法”属性会在第9章讨论。

help内建函数是非常有用的。可以得到关于函数,包括它的文档字符串信息:

Help on function square in module __main__:
 
square(x)
    Calculate the square of the number

并非真正函数的函数

数学意义上的函数,总在计算其参数后返回点什么。python有些函数却并不返回任何东西。

Python的函数就是函数,即便它从学术上讲并不是函数。没有return语句,或者虽然有return语句,但是return后边乜有跟任何值得函数不返回值:

def test():
    print 'this is michael'
    return
    print 'this is not'
>>>x = test()
this is michael
>>>x
>>>print x
None

可以看到,return后边的语句被跳过了(类似于循环中的break`语句,不过这里是跳出函数)。

x貌似没东西,但是其实有个很熟悉的值None。所以,所有的函数的确否返回了东西:当不需要它们返回值得时候,它们返回None。看来刚才“有些函数并不是真的是函数”的说法有些不公平了。

参数魔法

函数使用起来简单,创建起来也并不复杂。但函数参数的用法有时候就有些神奇了。

值从哪里来

参数错误的话显然会导致失败(一般来说,这时候就要用断言和异常)。

写在def语句中函数名后面的变量通常叫做函数的形参(parameter),而调用函数的时候提供的值是实参(argument)或者成为参数

我能改变参数吗?

def try_to_change(n):
    n = "Mr. Michael"
name = "qq"
try_to_change(name)

具体的工作方式类似这样:

>>>name= "qq"
>>>n = name    #这句的作用基本上等于传参
>>>n = "qq"
>>>name
"michael"

上面的例子中,由于参数是字符串(不可变序列),即无法被修改(也就是说只能用新的值覆盖)。但是,如果将可变的数据结构如列表用作参数的话,那么就有可能改变了。

这里具体例子就不讲了,因为再看《js高级程序设计》时,有相关类似的概念。值传递,引用传递。

为什么要改变参数

使用函数改变数据结构(比如列表或字典)是一种将程序抽象化的好方法。

关键字参数和默认值

目前为止,我们使用的参数都是位置参数,因为它们的位置很重要,事实上比它们的名字更重要。

def hello(greeting='hello',name='michael'):
    print '%s,%s'%(greeting,name)
>>>hello("qiuqiu",greeting="hah")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-42-311701c038b1> in <module>()
      1 def hello(greeting='hello',name='michael',):
      2     print '%s,%s'%(greeting,name)
----> 3 hello("qiuqiu",greeting="hah")
 
TypeError: hello() Got multiple values for keyWord argument 'greeting'

错误的意思,按照我自己的理解就是,为参数greeting赋予了多个值。这时候肯定就会出错了!为什么会这样呢?

位置参数和关键字参数混合使用的情况,位置参数是要放在关键字参数之前的。这里,不是这个原因。

我猜想 位置参数和位置肯定有关系,当使用它时,它会默认赋值给它位置对应的参数,那么,这里就是greeting。所以呢,这里才会赋值两次。做修改:

def hello(name='michael',greeting='hello'):
    print '%s,%s'%(greeting,name)
>>>hello("qiuqiu",greeting="hah")
hah,qiuqiu

默认参数值在函数被定义时已经计算出来,而不是在程序运行时。Python程序员经常犯的一个错误是把可变的数据类型(例如列表或者字典)当做默认参数值。

收集参数

有些时候可以让用户提供任意数量的参数是很有用的。

def print_params(*params):
    print params

参数前加*,结果打印出来是元祖。参数前的星号将所有值放置在同一个元祖中。可以说是将这些值收集起来。同时,也能和普通参数联合使用:

def print_params2(title,*params):
    print title
    print params
print_params2("test",1,2,3)
test
(1, 2, 3)

星号的意思就是“收集其余的位置参数”。如果不提供任何供收集的元素,params就是个空数组。

print_params2('nothing')  
nothing
()

能不能处理关键字参数呢?

>>>print_params2('humm',something=42)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-31af1f150edb> in <module>()
----> 1 print_params2('humm',something=42)
 
TypeError: print_params2() got an unexpected keyword argument 'something'

使用两个**,能处理关键字参数的“收集操作”。

def print_params3(**params):
    print params
print_params3(x=1,y=2,z=3)
{'y': 2, 'x': 1, 'z': 3}

返回的是字典而不是元祖了。放在一起看看:

def print_params4(x,y,z=3,*pospar,**keypar):
    print x,y,z
    print pospar
    print keypar
print_params4(1,2,4,"michael",name="michael",age="24")
1 2 4
('michael',)
{'age': '24', 'name': 'michael'}

参数收集的逆过程

如何将参数收集为元祖和字典已经讨论过了,但是事实上,如果使用***的话也可以执行相反的操作。看如下例子:

#定义函数
def add(x,y): 
    return x+y

有一个由两个数字组成的元祖:params=(1,2)

此时使用*元算符就简单多了——不过是在调用而不是在定义时使用,作用就相反了!
栗子1:

>>>add(*params)
3

栗子2:

def hello3(greeting="hello",name="world"):
    print '%s,%s'%(greeting,name)
params={'name':'michael','greeting':'well done'}
hello3(**params)
well done,michael    #结果

作用域

什么是变量?可以把它们看作是值的名字。在执行x=1赋值语句后,名称x引用到值1.这就像用字典一样,键引用值,当然,变量和所对应的值用的是个“不可见”的字典。实际上这么说已经很接近真实情况了。内建的vars函数可以返回这个字典:

>>>x=1
>>>y=1
>>>scope=vars()
>>>scope['x']
1
  • vars可以返回全局变量的字典。

  • locals返回局部变量的字典。

vars函数官方说明
这类“不可见字典”叫做命名空间或者作用域。

除了全局作用域外,每个函数调用都会创建一个新的作用域:

>>>def foo():x=42
>>>x=1
>>>foo()
>>>x
1

当调用foo的时候,新的命名空间就被创建了,它作用于foo内的代码块。赋值语句x=42只在内部作用域(局部命名空间)起作用,它并不影响外部(全局)作用域中的x

函数内的变量被称为局部变量(local variable)。

太痛苦了,这里的知识之前在学习JS时就已经了解的挺多,作用域链等等。还是记载以下我遗忘的知识好了。不赘述了。

x='michael'
def print_name(x):
    print x+x
print_name('qiuqiu')
qiuqiuqiuqiu    #结果

这里因为参数名和全局变量名重复了,因此,全局变量就被屏蔽了(如果不重复,是可以读取到全局变量值的)。我记得在JS中时,也有类似知识点,会逐步向上搜索作用域链中的变量值。

那么该怎么达成效果呢?怎么避免被屏蔽呢?使用globals函数获取全局变量值!

x='michael'
def print_name(x):
    print x+globals()['x']
print_name('qiuqiu')
qiuqiumichael   #结果

除非告知python将其声明为全局变量,否则,在函数内的新变量赋值会自动成为局部变量:

x=2
def gl(x):
    global x
    x+=2
    print x
gl(3)
x
File "<ipython-input-76-22d2ecf63f0c>", line 2
    def gl(x):
SyntaxError: name 'x' is local and global

为啥这里出错了呢?因为x作为形参,是局部变量,而函数里通过global又定义x是全局变量,因此出现了错误提示中的错误。

嵌套作用域(闭包)

python的函数是可以嵌套的,也就是说可以将一个函数放在另一个里面。

万万没想到,又看到闭包了!python中也是有闭包的嘛,看来各个语言的机理概念都大同小异啊~

在其他函数内写函数:

def multiplier(factor):
    def multiplyByFactor(number):
        return number*factor
    return multiplyByFactor

每次调用外层函数(此处的multiplier),它内部的函数都被重新绑定,factor变量每次都有一个新值!

>>>double=multiplier(2)
>>>double(5)
10
>>>multiplier(5)(4)
20

类似multiplierByFactor函数存储子封闭作用域的行为叫做闭包(closure)。

外部作用域的变量一般是不能进行重新绑定的。但是python3中,nonlocal关键字被引入。它和global关键字的使用方式类似,可以让用户对外部作用域(但并非全局作用域)的变量进行赋值。

递归(recursion)

递归简单来说就是引用(或者调用)自身的意思。

def recursion():
    return recursion()

为了深入了解它,读者应该买本计算机科学方面的好书。常用python解释器也能帮助理解。

无穷递归(infinite recursion),类似于以white True开始的无穷循环,中间没有break或者return语句。

有用的递归函数包括以下部分:

  • 当函数直接返回值时有基本实例(最小可能性问题)。

  • 递归实例,包括一个或者多个问题最小部分的递归调用。

这里的关键就是将问题分解为小部分,递归不能永远继续下去,因为它总是以最小可能性问题结束,而这些问题又存贮在基本实例中的。(就不能讲人话吗?!读不懂……)

两个经典:阶乘和幂

阶乘

可以使用循环:

def factorial(n):
    result=n
    for i in range(1,n):
        result*=i
    return result   

关键在于阶乘的定义:

  • 1的阶乘是1

  • 大于1的数n的阶乘是n乘n-1的阶乘
    现在看看递归的版本:

def factorial(n):
    if n==1:
        return 1
    else:
        return n*factorial(n-1)

假设需要计算幂,就像内建函数pow函数或者**运算符一样。先看一个简单的例子:power(x,n)(x的n次幂)。

def power(x,n):
    result =1
    for i in range(n):
        result*=x
    return result

把它改为递归版本:

  • 对于任意数字x来说,power(x,0)是1; 这就是上面递归条件的第一个,最小可能性问题吧

  • 对于任意大于0的数来说,power(x,n)是x乘以power(x,n-1)的结果。

理解定义是最困难的部分——实现起来就简单了。

def power(x,n):
    if n==0:
        return 1
    else:
        return x*power(x,n-1)

提示:如果函数或者算法很复杂而且难懂的话,在实现前用自己的话明确一下定义是很有帮助的。

函数式编程

python在应对“函数式编程”方面有一些有用的函数:

map

使用map函数将序列中的元素全部传递给函数

>>>map(str,range(10))    #Equivalent to [str(i) for i in range(10)]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

map函数:

Apply function to every item of iterable and return a list of the results.

filter

filter函数可以基于一个返回布尔值的函数对元素进行过滤:

def func(x):
    return x.isalnum()

>>>seq=['foo','x41','?!','***']
>>>filter(func,seq)
['foo','x41']

Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)]
str.isalpha()
Return true if all characters in the string are alphabetic and there is at least one character, false otherwise.

本章小结

这章的知识确实有点多啊,递归一直不是特别灵活运用,或许真该找本书看看。

--结束END--

本文标题: 《Python基础教程》第六章--读书

本文链接: https://lsjlt.com/news/192947.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 《Python基础教程》第六章--读书
    本章会介绍如何将语句组织成函数。还会详细介绍参数(parameter)和作用域(scope)的概念,以及递归的概念及其在程序中的用途。 懒惰即美德 斐波那契数列:任何一个数都是前两个数之和的数字序列。 创建函数 内建的callable函...
    99+
    2023-01-31
    第六章 基础教程 Python
  • Python-第一章(开发基础)
    1.    机器语言 = 机器指令 = 二进制代码   汇编语言就是把二进制变成了英文,开发效率低。   编译型语言:C   C++   Delphi  。。。   解译型语言:Python  php   java 。。。     好处:...
    99+
    2023-01-31
    基础 Python
  • 第一章 Python基础知识
    1.1 介绍1.1.1 特点Python是一种面向对象、解释型计算机程序设计语言。语法简洁清晰,强制用空白符作为语句缩进。Python具有丰富和强大的库,又被称为胶水语言。能把其他语言(主要C/C++)写的模块很轻松的结合在一起。1.1.2...
    99+
    2023-01-31
    基础知识 Python
  • python第一章计算机基础
    第一章 计算机基础 1.1 硬件 计算机基本的硬件由:CPU / 内存 / 主板 / 硬盘 / 网卡 / 显卡 / 显示器 等组成,只有硬件但硬件之间无法进行交流和通信。 1.2 操作系统 操作系统用于协同或控制硬件之间进行工作,常见的操...
    99+
    2023-01-31
    计算机 基础 python
  • 第1章 python 基础语法(3)
    =================目录==================1.8 字典1.9 字典练习2.0/2.1 流程控制-if条件判断 ======================================= dic={}字典是...
    99+
    2023-01-31
    语法 基础 python
  • 流畅的python读书笔记-第十章-继
    推出继承的初衷是让新手顺利使用只有专家才能设计出来的框架。——Alan Kay 子类化内置类型很麻烦 (如 list 或 dict)) ,别搞这种 直接子类化内置类型(如 dict、list 或 str)容易出错,因为内置类型的 方法...
    99+
    2023-01-31
    第十章 流畅 读书笔记
  • python核心编程2 第六章 练习
    6-2. 字符串标识符.修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来辅助 1...
    99+
    2023-01-30
    第六章 核心 python
  • 菜鸟python之路-第五章(记录读书点
    1、数字类型 python支持多种数字类型:整型、长整型、布尔型、双精度浮点型、十进制浮点型和复数 。 创建数值对象并赋值 aint=1 along=-999999999999999L afloat=3.1415973434325 ac...
    99+
    2023-01-31
    菜鸟 之路 第五章
  • Python 3基础教程24-读取csv
           本文来介绍用Python读取csv文件。什么是csv(Comma-Separated Values),也叫逗号分割值,如果你安装了excel,默认会用excel打开csv文件。 1. 我们先制作一个csv文件,example...
    99+
    2023-01-31
    基础教程 Python csv
  • Python 编程基础 | 第五章-类 | 5.2、属性成员
    一、属性成员 属性成员是指类中定义的变量,即属性,根据定义位置,又可以分为类属性和实例属性,下面分别进行介绍。 1、实例属性 实例属性是指定义在类的方法中的属性,该属性属于当前实例,例如:定...
    99+
    2023-10-26
    python 开发语言
  • Python基础教程
    6.4.5 参数收集的逆过程 假设有如下函数: def add(x,y): return x+y 比如说有个包含由两个相加的数字组成的元组: params = (1,2) 使用*运算符对参数进行“分配”,不过是在调用而不是在定义时使用: ...
    99+
    2023-01-31
    基础教程 Python
  • Redis基础教程第6节 List
    list是一个内部采用双向链表(double linked list) 结构,像列表两端添加元素的时间复杂度为O(1)。主要功能是push、pop、获取一个范围的所有值等,操作中key理解为链表的名字。链表...
    99+
    2024-04-02
  • Python基础(六)——面向对象编程
      这一部分难得和 Java 较为一致,直接写个例子: 1 class Stu: 2 def __init__(self, name, id): # 构造方法 3 self.name = name 4 ...
    99+
    2023-01-31
    面向对象 基础 Python
  • Python Numpy-基础教程
    目录 1. 为什么要学习numpy 2. Numpy基本用法 2.1. 创建np.ndarry 2.2. Indexing and ...
    99+
    2023-01-30
    基础教程 Python Numpy
  • 《python核心教程2》第十章 练习
    10-6.改进的open()。为内建的open()函数创建一个封装。使得成功打开文件后,返回文件句柄:若打开失败则返回给调用者None, 而不是生成一个异常。这样你打开文件就不需要额外的异常处理语句。 1 def openfile(f...
    99+
    2023-01-30
    第十章 核心 教程
  • 《python核心教程2》第九章 练习
    9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做Python , Perl, Tcl, 等大多脚本文件的注释符号.附加题: 处理不是第一个字符开头的注释. 1 filename = input...
    99+
    2023-01-30
    第九章 核心 教程
  • android开发基础教程—SharedPreferences读写
    代码如下: public class MainActivity extends Activity { @Override protected void onCreate(Bu...
    99+
    2022-06-06
    android开发 教程 Android
  • 【python基础教程】csv文件的写入与读取
    ✅作者简介:大家好我是hacker707,大家可以叫我hacker 📃个人主页:hacker707的csdn博客 🔥系列专栏:python基础教程 💬...
    99+
    2023-09-28
    python pycharm
  • python入门基础教程
    Python是一门简单易学、功能强大的编程语言,适合初学者入门。下面是一个简要的Python入门基础教程,帮助您快速上手Python编程。1. 安装Python:首先,您需要在计算机上安装Python解释器。您可以从Python官方网站(h...
    99+
    2023-10-25
    python 入门 基础教程
  • 《python语言程序设计基础》(第二版)第二章课后习题参考答案
    第二章 Python程序实例解析 文章目录 2.1 温度转换2.2 汇率兑换2.3 绘制彩色蟒蛇2.4 等边三角形的绘制2.5 叠加等边三角形的绘制2.6 无角正方形的绘制2.7 六边形的绘制...
    99+
    2023-10-12
    python 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作