admin 发布的文章

套娃式观看凤凰传奇视频后,记录指路部分演唱会合集,便捷听歌。

演唱会

【超清】凤凰传奇交响音乐会 2014 Phoenix Legend Symphonic Concert?

【凤凰传奇】2015“我是传奇X”北京跨年演唱会

【凤凰传奇】2016新年交响乐演唱会【分集版】

【凤凰传奇】2016新年交响乐演唱会【全场剪辑版】

音乐节

个人拍摄,不同视角链接

凤凰传奇武汉音乐节|珍贵同框影像观众声音超大

凤凰传奇佛山音乐节|上!新!歌!了!

【高清】凤凰传奇广州音乐节|我们又回到了第二个故乡

凤凰传奇南京江豚音乐节|后排品质蹦迪今年最佳音响

凤凰传奇太原半糖音乐节|收音超好氛围超顶且有等爱的玫瑰

凤凰传奇乌鲁木齐营地音乐节|往返7600公里的周末发癫之旅

凤凰传奇赤峰音乐节我先疯为敬

Python的模块为日常编程中许多问题提供了标准的解决方案,同时也能让我们更加简洁优雅地管理代码。

模块

定义:
每个模块是由1个或多个Python文件构成。是相关的类、函数和变量所组成的一个集合。

它可以被其它代码引入并直接使用。

通常,一个模块中的各个功能是相互关联的。

模块中的函数就像是积木,用一块一块的积木搭建成一个完整的图形,搭好的图形就是模块。

了解完模块的基本概念后,先来看看最常接触的第一大类模块:内置模块

内置模块是在安装Python时自带的模块。Python提供了大量丰富且高质量的内置模块来帮助完成一些系统化工作。

比如,生成一个随机的数字可以使用random模块,要处理日期和时间则可以通过datetime模块等。

为了使用这些模块,首先需要通过关键词import导入模块

导入模块(I)

import random
randomNum = random.random()
print(randomNum)

代码的作用
这三行代码输出了一个随机数。

第一行导入了random模块,该模块用于生成随机数;
第二行将生成的随机数赋值给了变量randomNum;
第三行输出了randomNum这个变量的数值。

import
关键字import,中文意思是“导入”,表明我们要在这里导入模块。

模块的名称
一个名为random的模块,该模块用于生成一个随机数。

模块内的函数
导入random模块后,就可以通过 random.xxx() 来使用该模块中的所有函数。

这里,我们调用了random模块里的random()函数,该函数用于生成一个0到1的随机浮点数。

模块内的函数
random模块中还有其它的函数,可以根据自己的需要来调用。

比如,想生成一个在1到7之间的随机整数,可以使用random模块里的randint()函数,代码为:random.randint(1,7)

代码小结
要导入模块时,就可以使用这样的格式:

使用import导入模块后,除了可以获取到模块内的函数,还可以获取到该模块中的类。通过调用类里面的方法,来实现某一功能。

比如,要获取今天的日期,就需要用到datetime模块里的date类,以及该类中的today()方法。

import datetime
todayDate = datetime.date.today()
print(todayDate)

导入模块
使用关键字import,中文意思是“导入”,表明我们要在这里导入一个名称为datetime的模块。

模块中的一个类
一个类,表明我们在调用datetime模块里的date类。

date类是一个日期类,里面提供了一些关于日期的方法与属性。

date类里面的某一个方法
一个方法,表明我们要调用的today()从属于date类。

该方法用于获取当前的本地日期。

代码小结
导入模块后,想获取到该模块中的类里面的某一个方法时,就可以使用这样的格式:

小练习

使用import导入random模块。

使用该模块下的random()函数,生成一个0到1之间的随机浮点数,并使用print()将结果输出。

import random
print(random.random())

获取今天日期的年份,并判断跟实际今年的年份(2022)是否相等。相等输出True,不相等输出False。

import datetime
today = datetime.date.today()
year = today.year
print(year == 2022)

不难看出,一个模块是由很多类和函数组成的。

有时候只想导入(import)模块里面的一部分内容,可能是一个类或是一个函数。 比如,我们只希望导入datetime模块中的date类。

这时候,就可以用到 from...import...

导入模块(II)

from datetime import date
todayDate = date.today()
print(todayDate)

两个关键字
第一个关键字from允许我们从模块中导入一个指定的部分。

这两个关键字,表明从datetime模块里导入date类。

模块的名称
一个名为datetime的模块,表示要从该模块中导入某个类。

一个类
一个类,表明我们要调用的date类属于datetime模块。

date类里面的某一个方法
一个方法,表明我们要调用的today()从属于date类。

可以看到,使用from...import...这种形式时,调用datetime模块中的类或函数时不需要datetime.前缀

代码小结
当我们只想导入模块里面的一部分内容时,就可以使用这样的格式:

第三方模块

学习了导入模块的两种方式,但是导入的都是内置模块。这些模块是Python自带的,具有较高的通用性。

除此之外,我们还会接触到许多的第三方模块。这些非内置的模块由其他的开发者所编写,提供给公众免费使用,功能更加个性化。可以从Python Package Index上找到自己需要的模块。

内置模块可以直接导入后使用,而非内置的模块则需要先进行安装,然后才能导入使用。

安装模块

为了安装第三方模块,需要一个叫作 pip 的工具。

在安装Python环境的时候,pip工具已经随着一起自动安装了,现在可以直接在电脑上使用pip工具来安装第三方模块。

安装第三方模块的方式在不同的电脑系统上略微有些不同

Windows

要使用pip工具安装第三方模块,需要在Windows的命令提示符里进行。

可以使用以下两种方式打开命令提示符:

  1. 在电脑左下角「开始菜单」旁的搜索栏里输入cmd
  2. 同时在键盘上按下快捷键WINR,在运行框里输入cmd

打开一个Windows命令提示窗口,就可以开始安装第三方模块了。

只需要在命令提示符的窗口里,使用 pip3 install「ModuleName」命令。这里,「ModuleName」是你所选择的模块的名称。

假如我们想制作一个可交互的柱状图,可以通过第三方模块 pyecharts,该模块是一个强大的数据可视化工具。

直接在终端中输入:pip3 install pyecharts==1.8.1 ,然后敲击回车键,就能进行安装。

这里由于pyecharts的特殊性,在安装时要指定版本1.8.1,而其它大多数模块都可以直接使用模块名安装。

如果在自己电脑上安装不上或安装缓慢,可在命令后添加如下配置进行加速:-i https://pypi.tuna.tsinghua.edu.cn/simple/

pip3 install pyecharts==1.8.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/

点击回车后,会出现很多的安装信息。当看到「Successfully installed...」或显示「Requirement already satisfied」的时候,说明模块已经安装成功。

可能会遇到黄色的警告,这是在提示需要升级pip工具。可以选择忽视,也可以按照指示在终端中输入「pip install --upgrade pip」进行升级。

安装过程如图所示。

macOS

要使用pip工具安装第三方模块,需要在macOS的终端里进行。

我们可以点击「启动台」后,在上方的搜索栏里输入终端,然后打开即可。

打开终端窗口,就可以开始安装第三方模块了。

只需要在终端窗口里,使用 pip3 install「ModuleName」命令。这里,「ModuleName」是你所选择的模块的名称。

假如我们想制作一个可交互的柱状图,就可以通过第三方模块 pyecharts 来完成。

直接在终端中输入:pip3 install pyecharts==1.8.1 ,然后敲击回车键,就能进行安装。

这里由于pyecharts的特殊性,在安装时要指定版本1.8.1,而其它大多数模块都可以直接使用模块名安装。

如果在自己电脑上安装不上或安装缓慢,可在命令后添加如下配置进行加速:

pip3 install pyecharts==1.8.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/

点击回车后,会出现很多的安装信息。当看到「Successfully installed...」的时候,说明模块已经安装成功。
安装过程如图所示。

示例

安装成功后,就可以关闭当前窗口,回到编辑器里使用该模块来绘制柱状图了。和内置模块一样,我们需要导入模块。

第一行代码:
使用 pyecharts.charts 的方式,访问了pyecharts模块里的子模块charts
然后,通过from...import...,从pyecharts模块的子模块charts里导入了Bar类。

第二行代码:
使用from...import...,从pyecharts模块中,导入子模块options,并将其简写为了opts

这里,import...as...是用于在导入一个模块的同时,为该模块取一个别名。

这是为了之后在代码中使用该模块时能更加方便,不用再通过options调用,可以直接通过opts。

导入完成后,我们就可以通过这些模块,绘制出一个可交互的柱状图啦。

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()

bar.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
bar.set_global_opts(title_opts=opts.TitleOpts(title="某商场销售情况"))

bar.render("bar.html")

小练习

引入math模块
使用import来导入内置模块:math,该模块提供了大量的数学运算函数。

导入模块后,完成以下两个操作:

  1. 通过math模块内 sqrt() 函数,输出99的开平方结果;
  2. 通过math模块内 fabs() 函数,输出-0.03的绝对值。
import math
print(math.sqrt(99))
print(math.fabs(-0.03))

计算平均值
statistics是Python中的一个数学统计模块。

使用statistics.mean()可以计算出一个列表的平均值,只需要将列表传入到括号中即可。

使用import导入statistics模块,并定义一个列表numList = [10, 99, 78, 50]。使用statistics.mean()计算该列表的平均值,并输出。

import statistics
numList = [10,99,78,50]
print(statistics.mean(numList))

from...import...
使用from...import...来完成上一道题目

定义一个numList = [10, 99, 78, 50],使用statistics模块下的mean()来计算该列表的平均值,并输出。

from statistics import mean
numList = [10,99,78,50]
print(mean(numList))

在生活中,我们通过特征与功能来描述一个具体对象,转换到代码中就变成了数据与函数。
回顾已经学过的内容,我们学习了用来存储数据的变量与用来存储代码的函数。
现在让我们把变量与函数打包,来学习在程序中创建类与对象。

类代表着一类事物,比如人类,鸟类,汽车,电脑。当我们提起这些事物的时候,我们并不特指某一个具体的东西,比如人类是泛指抽象的全人类

而对象指的是类的实例,比如人类的对象是某个具体的人,如张三,李四,tony和kevin。

类与对象

类代表一些拥有相同特性与功能的事物,如鸟类,人类,猫类等。

类中的某一个具体实例称为这个类的实例对象,简称为对象。

若请你介绍一下自己的手机,你会如何去做?
你可以通过颜色、型号、容量大小,屏幕尺寸等数据来描述它的特征;
也可以用拍照、安装应用、打电话等操作来描述它的功能。

我们可以把拥有上述特性的设备都归类于手机,即手机就是一个类。

手机的特征称为这个类的属性,手机的功能称为这个类的方法。

属性与方法

定义:
属性用来描述这个类的一些特征,如品牌,颜色,型号是手机的属性。

方法用来表现这个类的一些功能,如拍照,打电话等是手机的方法。

在Python中通过class关键字来创建一个类。
为了方便理解,接下来在程序中定义一个手机类。
并为手机设定两个方法:打电话,发短信。

类的定义

class Phone():
    def makeCall(self, who):
        return f"正在拨打电话给{who}"

    def sendMsg(self, who, txt):
        return f"正在发送短信给{who}, 内容为{txt}"

代码的作用
class定义一个类,并命名为Phone

第2~6行,为该类添加了打电话和发短信两个功能。即定义了两个方法makeCallsendMsg

第2,3行,makeCall方法接收联系人的名字为参数,并将文字格式化输出。

第5,6行,sendMsg方法接收联系人的名字与短信内容为参数,并将文字格式化输出。

关键字
class,在程序中定义类的关键字。

类名
一串文字,为类定义的名称。
为了区分类与函数,类的名称首字母建议大写。

括号
一对括号,定义类的标准写法。

:
一个冒号,表明接下来缩进的代码是属于这个类的。

四个空格
一个缩进,表示该代码块属于Phone这个类。

方法名
类中的两个特殊函数,称为方法。
方法又被称为成员函数,用来表现这个类的一些功能。

成员函数的第一个参数为self

特殊的参数
self参数,由程序自动传入的参数,指调用该方法的对象。

第一个参数为self,是定义实例方法的固定写法。

代码小结
当我们要定义一个类时就需要这几个部分

类是抽象的,我们要使用类,就需要实例化一个对象。

对象是以类为模板创建的。

这个过程类似于以人类的共同特性为模板,创造一个特定的人。
可以这样说,你就是人类的一个实例对象。

接下来学习一下如何通过类来实例一个具体的对象。
用Phone类来实例化两个对象表示我的手机与你的手机。

实例化对象

class Phone():

    def makeCall(self, who):
        return f"正在拨打电话给{who}"

    def sendMsg(self, who, txt):
        return f"正在发送短信给{who}, 内容为{txt}"

myPhone = Phone()
yourPhone = Phone()

ret = myPhone.makeCall("Tony")
print(ret)
ret2 = yourPhone.sendMsg("Jeremy", "中午吃啥?")
print(ret2)

代码的作用
将刚才定义好的Phone类拿过来,并实例化两个对象myPhoneyourPhone

第9,10行,创建Phone的对象myPhoneyourPhone

第12行,调用myPhone的方法makeCall,把结果存储到ret中。

第14行,调用yourPhone的方法sendMsg,把结果存储到ret2

对象名
一个变量名,为对象设定的名称。

类名
定义好的类名。

括号
括号,表示调用Phone类实例化一个对象。

对象
对象名称,用对象名调用指定的方法。

句点
一个句点【.】。

用句点连接对象名与对象的方法,称为句点表示法。

例如第11行,表示myPhone使用了他的方法(功能)makeCall(打电话)。

方法名
方法名,对象要调用的方法名称。

实参
调用方法时传递的实参。

调用对象的方法时,不需要为self参数传递实参。

这里,第11行的“Tony”实参传递给makeCall“who”形参。

第13行的“Jeremy”实参传递给sendMsg“who”形参,“中午吃啥”传递给sendMsg“txt”形参。

代码小结
当我们要实例化对象时就需要这几个部分

小练习

实例化对象
为Cat实例化一个对象mimi,并使用该对象调用talk方法。

class Cat():
    def talk(self):
        print("喵喵喵")

# 创建一个Cat对象,并存储在mimi中
mimi = Cat()
# 调用mimi的方法talk
mimi.talk()

类的属性与初始化

在刚才的代码中,创建了一个包含两个方法的Phone类,并且创建两个不同的实例对象去调用这些方法。

现在让我们为类设置属性,并在创建实例化对象时,初始化该属性的值。

手机的属性有:颜色,品牌。

class Phone():
    def __init__(self, bd, clr):
        print("创建实例对象时,自动调用此方法")
        self.brand = bd
        self.color = clr

myPhone = Phone("华为", "白色")
yourPhone = Phone("苹果", "黑色")
print(f"我有一个{myPhone.color}的{myPhone.brand}手机")
print(f"你有一个{yourPhone.color}的{yourPhone.brand}手机")

代码的作用
Phone类添加品牌(brand)与颜色(color)两个属性。

第2行,定义初始化方法__init__并设定两个参数bdclr

第8,9行,创建实例化对象myPhoneyourPhone,并为__init__方法传递参数两组不同的参数。

第10,11行,分别格式化输出实例对象的colorbrand属性

初始化方法
初始化方法__init__,是一个特殊的方法。

init左右两边各有两个下划线,即整个名称共有四个下划线。

初始化类似于出厂设置,表示“开始时做好准备”,会在创建对象时自动被调用

特殊的参数
self参数,是调用方法时由程序自动传入的参数,指实例化后的对象。

句点
一个句点,用来连接对象名与属性。

因为这里还没有创建对象,所有对象名用self参数代替。

属性
对象的两个变量,称为属性。

与之前创建的变量不同,brandcolor是专属于该类对象的变量,只能被类的对象使用。

参数
初始化函数的两个形参名。接收传递的数据后赋值给对象的两个属性brandcolor

实参
两组数据。在创建对象时,为初始化函数中的brandcolor传递的数据。

使用属性
两个对象分别使用它们的属性,并格式化输出内容。

代码小结
当我们初始化属性时需要这几个部分

特殊的self参数

通过前面的内容知道,对象的属性与方法需要用句点表示法将对象名与方法名连接在一起。

但是在定义类时,我们还不知道要创建哪些对象,所以self的作用就是将实例化的对象名称(引用)传递到方法中。

比如在myPhone对象中,self.brand 代表的是myPhone.brand

初始化过程
在创建一个实例对象时,程序会自动调用init方法。

最后

总结一下类与对象的注意事项。

方法与属性只能被实例对象调用

就像append只能被列表使用一样,方法与属性只能用句点表示法被该类的实例使用,否则就会出错。

函数与方法
在Python中有着一切皆对象的说法,我们创建的字符串、列表、元组等本质上都是该类型的一个对象。

所以直接调用的print()range()为函数,用句点表示调用的append()keys()等为某个对象的方法。

小练习

属性的使用
现有一个Cat类,并为该类初始化了两个属性名称(name)与品种(breed)。

假设我有一只“橘猫”叫做“大黄”,实例化一个Cat对象存储到myCat中,并传递参数"大黄", "橘猫"。

假设你有一只"布偶猫"叫做“土豆”,实例化一个Cat对象存储到yourCat中,并传递参数"土豆", "布偶猫"

最后分别按照“有一只xx叫做xxx”的格式输出(需要用到格式化输出)。

class Cat():
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
    def talk(self):
        print("喵喵喵")

# 实例化一个Cat对象存储到myCat中,并传递参数"大黄", "橘猫"
myCat = Cat("大黄", "橘猫")
# 实例化一个Cat对象存储到yourCat中,并传递参数"土豆", "布偶猫"
yourCat = Cat("土豆", "布偶猫")
# 分别按照格式输出字符串
print(f"有一只{myCat.breed}叫做{myCat.name}")
print(f"有一只{yourCat.breed}叫做{yourCat.name}")

判断用户是否为会员
现有一个User类,并为该类初始化了两个属性用户名(name)与是否为会员(isVIP)。

实例化一个User对象存储到tony中,并传递参数"Tony", True
实例化一个User对象存储到jeremy中,并传递参数"Jeremy", False
最后分别调用tony与jeremy的sayHi方法。

class User():
    def __init__(self, name, isVIP):
        self.name = name
        self.isVip = isVIP

    def sayHi(self):
        if self.isVip:
            print(f'尊贵的会员{self.name},欢迎您!')
        else:
            print(f'{self.name},欢迎您!')

# 实例化一个User对象存储到tony中,并传递参数"Tony", True
tony = User("Tony", True)
# 实例化一个User对象存储到jeremy中,并传递参数"Jeremy", False
jeremy = User("Jeremy", False)
# 分别调用tony与jeremy的sayHi方法
tony.sayHi()
jeremy.sayHi()

计算学生平均成绩
现有一个MathScore类,并为该类初始化了两个属性班级名称(name)与本学期数学成绩列表(scoreList)。

实例化一个MathScore对象存储到class32 中,并传递参数"三年级二班", [78, 99, 88, 87, 67]
最后调用class32的showMsg方法

class MathScore():
    def __init__(self, className, scoreList):
        self.className = className
        self.scoreList = scoreList
        self.studentNums = len(self.scoreList)

    def getSum(self):
        # 计算成绩总和
        s = 0
        for score in self.scoreList:
            # 注:s += score 为 s = s + score 的简写
            s += score
        return s

    def mean(self):
        # 计算成绩平均数
        return self.getSum()/self.studentNums

    def showMsg(self):
        print(f"{self.className}共有{self.studentNums}人,数学平均成绩为{self.mean()}")

# 实例化一个MathScore对象存储到class32 中,并传递参数"三年级二班", [78, 99, 88, 87, 67]
class32 = MathScore("三年级二班", [78, 99, 88, 87, 67])
# 调用class32的showMsg方法
class32.showMsg()

在 Python 中,我们可以使用【def 函数名(参数):】的方式定义函数。

如果我们把 def 定义的函数看作“有名字函数”,那么还有一类函数,其不需要显示定义函数名。

这就是匿名函数。

匿名函数

匿名函数是一种不需要为函数命名的函数定义方式,以 lambda 关键字开头。

匿名函数之所以叫匿名函数,是因为它没有函数名称。
本例中,我们是把一个匿名函数赋值给了变量 square,该变量就可以调用函数。

匿名函数的结构

square = lambda x:x*x
result = square(9)
print(result)

multiply = lambda x,y:x*y
newResult = multiply(9,10)
print(newResult)

代码的作用
这两段代码创建两个匿名函数,并且使用变量调用,传入参数,输出了结果。

lambda
一个关键字 lambda,用来创建匿名函数。

空格
一个空格,固定格式,关键字 lambda 和具体计算式之间的空格。

参数
这个位置表示该匿名函数的参数,为形参。
如果传入多个参数,需要使用“逗号”隔开。

冒号:
一个冒号是“匿名函数”的固定格式,冒号后面是具体如何计算冒号前面的输入数值。

表达式
冒号后面是函数的返回值,注意这里不需使用 return 关键字。

变量
将匿名函数赋给一个变量,再由该变量来调用函数。

调用函数
匿名函数同样需要被调用才能执行,调用仍然使用 ( ) 传参的方式实现。

变量
变量,这个变量会“接受”匿名函数返回出来的值。

代码小结
当要定义匿名函数时,可以使用这样的格式

小练习


定义一个“匿名函数”,它的功能是计算一个输入值的3次幂,将匿名函数赋值给变量power,然后输入一个数值 5,并输出计算结果。

power = lambda number:number*number*number
print(power(5))

立方体体积
定义一个“匿名函数”,它的功能是计算立方体的体积,其公式为:长高,将匿名函数赋值给变量 area。

然后传入参数10, 8, 6,并输出计算结果。

area = lambda length,width,height:length*width*height

print(area(10, 8, 6))

匿名函数使用起来比较方便,但是它也有局限性。
lambda 的主体是一个表达式,而不是一个代码块,不适合处理复杂的逻辑情况。
我们在创建函数时,如果需要处理较为复杂的逻辑,建议使用 def 创建函数,如本例所示,计算列表各元素的累加。

在之前的学习中,都是先定义函数以后,在代码的其他地方调用这个函数。
其实,在函数的内部还可以调用自己,这种调用自己函数就是递归函数

递归

一段程序调用自身的过程我们叫做递归,多见于函数调用函数自身。

当两面镜子相互之间近似平行时,镜中嵌套的图像是以无限递归的形式出现的。也可以理解为自我复制的过程

语言例子
如果我们用语言的形式表示递归的话,这个通俗的故事最能体现:

从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……

接下来,就在案例中,学习递归的使用方法和其中的程序运行逻辑。

递归

递归概念比较抽象,我们来一起梳理下。

假设创建一个递归函数,用于计算数字累加,传入数字 5 ,计算 5 以内的数字累加。
5+4+3+2+1+0

由于 5 大于 0,程序不会执行函数中 if 判断的代码块,而是返回 5 + sum(4)
这里的 sum(4) 又是一次 sum() 函数的调用,程序就会返回 4 + sum(3)

程序就一直调用自己,直到 sum(0),因为 if 语句的存在,它不需要等待 sum(0) 的计算了,而是直接给出结果 0
然后程序一路返回,回到最初的 sum(5),并给出最终的答案:5+4+3+2+1+0 = 15

递归函数会终止么?

在递归函数中,if 判断就是终止条件,在本例中当 n 小于等于 0,就返回 0 ,递归就终止了。
如果不加这个终止条件会无休止的递归下去,最终造成程序报错。

类似的,我们要算一个数的阶乘,一个正整数的阶乘是所有小于及等于该数的正整数的积,例如
5! = 5×4×3×2×1

我们可以用图中的代码,当 n > 0 的时候,函数会调用它本身,直到 n <= 0

小练习

200以内求和
写一个递归函数可以实现 200 以内的整数和。

将函数名命名为 sum,传入参数为 n。

# 定义名为sum()函数,传入参数n
def sum(n):
    # 如果n小于等于0
    if n <= 0:
        # 返回0
        return 0
    # 返回n加上sum(n-1)
    return n + sum(n-1)

# 调用sum()传入200并输出
print(sum(200))