python进阶数据分析_数据分析--Part 2: Python进阶

本文是Python进阶数据分析系列的第二部分,主要介绍了Python中的函数,包括函数定义、参数、返回值、匿名函数,以及面向对象编程的基础知识,如类、实例、属性和方法。通过示例详细讲解了如何定义和使用函数,如何创建和操作对象,以及类属性和类方法的概念。最后,提到了Python中模块和包的管理,包括导入模块、自定义模块和常用内置模块的使用。
摘要由CSDN通过智能技术生成

笔记内容来源:拉勾教育数据分析实战训练营

本篇是Part 2,python的进阶部分开始啦~~~~~~~

说明:理论部分是提炼的老师所讲,加上我自己看书添加的一些解释,代码部分有些会融合老师和我自己练习的写法,一起分享给大家

再啰嗦两句,关于拉勾教育数据分析实战训练营:

目前为止已经学习了近4个月的课程,已经学完Excel、数据分析思维、MySQL、Tableau、quickBI、神策、hive、统计学,每一阶段每一模块的知识都是在线自主学习,完成作业后解锁新课程,直播课会根据全体学员进度,收集疑问然后进行在线直播内容回顾和答疑以及作业讲解。每位讲师都很优秀,都有自己的授课特色所在,内容都是很干货的录好的内容,有些内容导师还会重新录制,不断迭代让学员达到更好的学习体验。作业批改、答疑导师西蒙(我接触最多的,经常麻烦他帮我解决问题)和班主任团子比较nice,认真负责,他们分别负责技术答疑和服务类的问题,平时有问题可以在微信群里问,可以单独聊也可以群里问,他们全天非工作日也会答疑。

在这里真心推荐下拉勾教育数据分析实战训练营:

1、课程体系最全面:课程内容有分析方法论、分析方法、Excel、Mysql、Tableau、Quick BI、神策平台、Hive、统计学、Python、挖掘算法、Spss等,是目前我看到的最全面的。

2、课程体系把握行业人才需求痛点:拉勾主营业务是招聘,最明白企业的人才需求,基于此设计的课程体系是比较贴近实际需求的。通过5个月10个阶段,从现状统计到预测分析、从业务数据到编程工具处理复杂业务逻辑数据,实现用数据驱动业务辅助决策,提升公司业绩。

3、课程学习模式灵活:大部分授课采用录播方式,学习完成后还有直播答疑。比直播打卡更容易安排自己的时间。

4、课程学习过程和结果有保障:学习成果作业检测+实时答疑+班主任督导,每个阶段每个模块的知识学完的作业可以锻炼实操。

5、项目实战内容丰富:也是我最看好的一点,涵盖了在线教育、电商等多个领域项目实战。

6、就业辅导+优秀内推:拉勾平台是互联网行业招聘大本营,这是天然优势。

~~~~~~~~~~~~~~~~~以下是笔记~~~~~~~~~~~~~~~~

四、Python进阶

1 函数

1.1 函数定义及调用

在Python在, 使用def关键字来定义函数

def hello(name):

print('hello',name)

hello('python')

# hello python

上面的代码定义了一个最简单的函数,它的作用就是打印出"Hello"加一个名字。看看它的结构:

1.2 函数的参数

函数的参数可以有一个,也可以有多个,也可以没有参数。这取决于在定义函数的时候如何定义参数部分。刚才我们定义的函数只有一个参数,现在我们定义两个参数的函数。

def hello2(name, sex):

if sex == '男':

print("Hello, Mr", name)

elif sex == '女':

print("Hello, Mrs", name)

这个函数有两个参数,name和sex(变量是形参),分别表示用户的名字和性别,传递的值是实参。

在调用的时候,要注意参数的顺序,不能前后颠倒。可以调用函数多次

hello("Zhang", "男")

hello("Wang", "女")

如果参数较多,记不清它们的顺序,可以写上参数名--关键字实参

hello(sex='男', name='Zhang')

默认值

使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。

def hello2(name, sex='女'):

if sex == '男':

print("Hello, Mr", name)

elif sex == '女':

print("Hello, Mrs", name)

hello2(name='Zhong')

hello2('zhong')

如果每一个参数都有默认值,在调用的时候甚至可以不传参数。

def hello2(name='Anonym', sex='女'):

if sex == '男':

print("Hello, Mr", name)

elif sex == '女':

print("Hello, Mrs", name)

hello2()

现在这个函数对于信息不完整的数据也有处理能力了。

如果在调用函数时,给形参提供了实参,将使用制定的实参值,否则将使用形参的默认值。

def hello2(name='Anonym', sex='女'):

if sex == '男':

print("Hello, Mr", name)

elif sex == '女':

print("Hello, Mrs", name)

hello2('li','男') #Hello, Mr li

1.3 函数的返回值

函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值,函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行。

def multiply(num1, num2):

return num1 * num2

print(multiply(2, 4))

multiply函数的功能是计算两个数相乘,我们传入两数字作为参数,希望能得到一个这两个数相乘的结果。multiply的最后一行使return 关键字将结果返回。通常在函数的最后一行返回结果,但有时候也有多种可能。

def permit(age):

if age >= 18:

print("准许进入")

return True

else:

print("禁止进入")

return False

print("end")

permit(18)

上面定义了一个只允许成年人进入的函数,如果年龄大于等于18岁,返回True,表示允许通过;如果小于18岁则不允许。虽然有两个return语句,但只返回一个结果,要么返回True要么返回False。注意在return语句执行完后,函数就会结束执行,在它之后的任何语句都不会再执行,所以上例中的“end”无论怎么样都不会被打印。

如果一个函数内没有任何return语句,那它的返回值就是None。

def do_nothing():

pass

print(do_nothing())

返回列表中的最大最小值

def find_min_max(nums):

nums.sort()

return nums[0], nums[-1]

min_max = find_min_max([2, 3, 5, 6, 1, 4])

print(min_max) #(1,6)

min, max = find_min_max([2, 3, 5, 6, 1, 4])

print(min, max) #1,6

1.4 匿名函数

定义了一个匿名函数

square1 = lambda n: n * n

相当于

def square2(n):

return n * n

print(square1(2))

print(square2(2))

lambda是Python中的关键字,它的作用就是用来定义匿名函数,匿名函数的函数体一般只有一行代码,省略了函数名和返回值语句。

key = lambda x: x[1]

key([1, 2]) # 2

key("abcd") # 'b'

key函数的作用就是返回序列中的第二个元素,在sort排序的时候就会以每个元素的第二个元素作为比对的依据。

再看两个例子:

plus = lambda x, y, z: x + y + z

print(plus(1, 2, 3))

#6

key参数使用每个原始的第二个索引的和作为排序依据

revenue = [('1季度', (5610000, 5710000, 5810000)),

('2季度', (4850000, 4850000, 4850000)),

('3季度', (6220000, 6320000, 6420000))]

revenue.sort(reverse=True, key=lambda x: sum(x[1]))

print(revenue)

#[('3季度', (6220000, 6320000, 6420000)), ('1季度', (5610000, 5710000, 5810000)), ('2季度', (4850000, 4850000, 4850000))]

2 面向对象

2.1 类和实例

面向过程:根据业务逻辑从上到下写代码。

面向对象:将变量与函数、属性绑定到一起,分类进行封装,每个程序只要负责分配给自己的功能,这样能够更快速的开发程序,减少了重复代码。

对象的属性就是可以精确描述事物的特点,对象的函数就是事物的行为。

类,它也是面试对象编程的基础。

class Dog:

pass

这样我们就定义了一个类,使用class关键字,加上一个类名,这样我们就定义了一个空的类。

类名一般使用名词,且使用驼峰式命名法。

类是创建对象的模板,对象是类的实例。类就像生产线,有了类,就可以生产出许许多多的相同对象。

使用上面的Dog类来创建一个Dog对象:

dog = Dog()

type(dog)

这里dog就是Dog的实例,通过内置的type函数,可以查看任何对象的类。

print(type(1)) #

print(type((1, 2))) #

print(type([1, 2])) #

它们分别是整数、元组和列表。

那dog的类型就是Dog。

class Dog:

pass

dog = Dog()

print(type(dog))

#

如果我们不知道一个对象是不是某种类型,就可以用type判断。

type('abc') == str # True

type(dog) == Dog # True

type(1) == int # True

也可以使用内置函数isinstance来判断对象与类的关系

isinstance('abd', str) # True

isinstance(1, int) # True

isinstance(dog, Dog) # True

2.2 对象的属性与方法

创建Dog类

class Dog:

def __init__(self):

self.breed = None

self.color = None

self.size = None

def eat(self):

print("I like bones")

def run(self):

print("I'll catch you.")

def bark(self):

print('Wang! Wang!')

类的每一个方法的第一个参数是 self ,必不可少,还必须位于其他形参的前面。但在调用的时候却不需要传参数给它。它是类方法和普通函数的区别,这个self代表的是实例自身,意思是“我的”,

创建Dog的实例

dog = Dog()

dog.eat()

dog.run()

dog.bark()

print('一只%s型%s色的%s' % (dog.size, dog.color, dog.breed))

调用方法

要调用方法,可指定实例的名称(这里是dog)和要调用的方法,并用句点分割。

调用不同的方法能打印出不同的内容,体现了不同的行为。但是最后一句话打印出来的内容却是None,因为我们还没有设置相应的属性。

设置属性

dog.breed = '哈士奇'

dog.color = '黑白'

dog.size = '大'

print('一只%s型%s色的%s' % (dog.size, dog.color, dog.breed))

# 一只大型黑白色的哈士奇

访问属性

要访问实例的属性,可使用句点表示法

print(dog.breed)

如果每个创建完每个对象之后还要一个个的设置属性,会很麻烦。我们可以使用__init__ 函数来接收始化参数,这样就可以把属性的值作为参数在初始化对象的时候就传给它。

__init__ 函数看起来与众不同的样子,它是Python的类用来初始化对象的构造函数,它的名字是固定的,必须这样写,创建对象时会首先调用它。改完后构造函数后代码如下:

class Dog:

# 构造函数,初始化函数

def __init__(self, breed, color, size):

self.breed = breed

self.color = color

self.size = size

def eat(self):

print("I like bones")

def run(self):

print("I'll catch your.")

def bark(self):

print('Wang! Wang!')

dog = Dog("哈士奇", '黑白', '中')

dog.eat()

dog.run()

dog.bark()

可以给参数默认值,就不用传递值给参数了

class Dog:

# 构造函数,初始化函数

def __init__(self, breed, color, size='大'):

self.breed = breed

self.color = color

self.size = size

def eat(self):

print("I like bones")

def run(self):

print("I'll catch your.")

def bark(self):

print('Wang! Wang!')

dog = Dog("哈士奇", '黑白')

对象自身的属性是直接可以方法里使用的,比如改造一下bark方法,让狗可以开口自我介绍

class Dog:

# 构造函数,初始化函数

def __init__(self, breed, color, size='大'):

self.breed = breed

self.color = color

self.size = size

def eat(self):

print("I like bones")

def run(self):

print("I'll catch your.")

def bark(self):

"""一只狗的自我介绍"""

print('Wang! Wang!')

print("一只%s型%s色的%s" % (self.size, self.color, self.breed))

dog2 = Dog('金毛犬', '金')

dog.bark()

# Wang! Wang!

一只大型金色的金毛犬

2.3 类属性与方法

2.3 类属性与方法

对象是从类创造的,对象的属性和方法虽然是在类中定义的,但它们的值是各个对象独有的,互相不能共享。而类也有属性和方法,且它们可以和类创建的所有对象共享。

先来定义一个类

class Goods:

def __init__(self):

self.name = ''

self.price = 0

self.discount = 1

Goods类有三个对象属性,每个商品有自己的名称、价格、折扣。

可以随意的创建商品

g1=Goods()

g2=Goods()

如何知道一共创建了多少个商品呢?可以给Goods类加一个计数器。

class Goods:

count = 0

def __init__(self):

Goods.count += 1

self.name = ''

self.price = 0

self.discount = 1

给Goods类加了一个属性count,每当调用 __init__ 函数时将它加1,就可以知道一共创建了多少商品对象了。这个count就是类属性,它可以通过对象访问,也可以通过类访问。

g1 = Goods()

g1.count # 1

g2 = Goods()

Goods.count # 2

即使没有定义对象,也可以直接访问count属性,这就是类属性,同样,类方法也不需要创建对象,通过类名就可以访问。

我们改造一下Goods类,给它增加一个属性id,表示商品唯一的序列号,为了保证id不重复,我们使用计数器,每创建一个商品给它加1。

class Goods:

id_count = 0

# 类方法

# 装饰器写法,classmethod用来定义类方法

@classmethod

def generate_id(cls):

cls.id_count += 1

return cls.id_count

def __init__(self):

# 商品唯一序号, 00001, 02738

# zfill函数表示用“0”将数字补足5位

self.id = str(self.generate_id()).zfill(5)

self.name = ''

self.price = 0

self.discount = 1

这里的 generate_id 方法就是一个类方法,它的上面一行有一个 @classmethod ,声明了它是类方法,它的参数不再是self,而是cls,指向类本身,用来在类方法内部访问类成员属性和方法。这个方法每次将id_count属性加1,并返回。

这种 @ 符号的写法叫做装饰器,装饰器是用来装饰函数的,不同的装饰器赋予函数不同的特殊功能。对于classmethod装饰器,大家只要知道它是用来定义类方法的就行了。

g1 = Goods()

g2 = Goods()

g1.id # 00001

g2.id # 00002

Goods.id_count # 2

2.4 一切皆对象

在Python中一切都是对象,我们使用的数字、字符串、函数甚至类本身,都是对象。

所有的对象都可以用type函数来判断它的类型,同时可以用dir函数来查看它的属性和方法。

dir(Dog)

会显示出dog对象的所有属性和方法,包括刚刚定义的那几个方法和属性。

对于对象,也可以使用help函数查看它的帮助文档。

帮助信息可以在定义的时候写入到代码里:

def bark(self):

"""一只狗的自我介绍"""

print('我是一只%s型%s色的%s' % (self.size, self.color, self.breed))

加上这句文档后,就可以使用help函数查看bark方法的帮助信息了,这有助于其他人使用我们的方法。

help(dog.bark)

help(Dog.bark)

一切皆对象是一句简单的话,但它的精神却很深邃,试试下面的代码

lst = []

lst.append(Dog)

dog = lst[0]('中', '黄')

lst.append(dog)

lst[1].bark()

lst[1].sleep = lambda: print('Good night.')

lst.pop().sleep()

有时候两个对象的值完全相同,我们可以说这两个对象是相等的,但不能说它们是同一个对象。

l1 = [1, 2, 3]

l2 = [1, 2,]

l1 == l2 # False

l2.append(3)

l1 == l2 # True

l1 is l2 # False

最后一行操作,使用 is 关键字来判断这两个对象是否是同一个对象,结果是False。它表明l1和l2是不同的对象,这一点可以使用id函数看出来:

id(l1)

id(l2)

分别返回两串不同的数字,这个一长串的数字代表了对象所指向的内存空间地址。

但赋值l3 =l1, l3会随l1变化,且指向同一内存空间地址,相当于同一个对象有两个名字

>>> l1 = [1,2,3]

>>> l3 = l1

>>> l3

[1, 2, 3]

>>> l1.append(4)

>>> l1

[1, 2, 3, 4]

>>> l3

[1, 2, 3, 4]

>>>

2.5 综合案例电商购物车商品统计分析

项目需求:可以设置每个商品的名称、价格、折扣率,用户将商品加入到购物车以后,能够立即显示所有商品、总价、折扣情况和实际需要支付的金额,也就是折扣后的金额。商品的名称、价格、折扣率都可以随意修改,且修改完成后,购物车中的相关信息和金额也会发生改变。

需求分析:在这个需求里面,提到了两个虚拟产物,商品与购物车,也就是说需要定义两个类。

class Goods:

"""商品类"""

id_count = 0

# 类方法

# 装饰器写法,classmethod用来定义类方法

@classmethod

def generate_id(cls):

cls.id_count += 1

return cls.id_count

def __init__(self, name, price, discount=1):

self.id = str(self.generate_id()).zfill(5)

self.name = name

self.price = price

self.discount = discount

def cal_price(self):

"""计算商品打折后的实际价格"""

return self.price * self.discount

#这是商品类,它有四个属性:ID、商品名称、价格、折扣,另外它还有一个函数,计算出商品打完折后的价格。接下来创建几个商品对象:

g1 = Goods('iPhone 11', 6000, 0.9)

g2 = Goods('U盘32G', 100, 0.8)

g3 = Goods('华为P40', 5000)

print(g1.name)

# 这样就创建了三个商品对象,并设置好了它们的名称、价格、折扣。接下来来编写购物车类:

class Cart:

"""购物车"""

def __init__(self):

self.cart = {}

self.goods_list = []

def add(self, goods, num=1):

"""向购物车中添加商品"""

if goods in self.goods_list:

self.cart[goods.id] += num

else:

self.goods_list.append(goods)

self.cart[goods.id] = num

def remove(self, goods, num):

"""从购物车减少或删除商品"""

if goods not in self.goods_list:

return

self.cart[goods.id] -= num

if self.cart[goods.id] <= 0:

del self.cart[goods.id]

self.goods_list.remove(goods)

cart是一个字典,用来保存商品和数量的对应关系,它的键名是商品ID(字符串);goods_list是一个列表,保存了购物车所有商品的详细信息(商品类实例),注意它们的数据结构。

有了Goods和Cart,我们就可以随意的增加删除商品,并可以随时查看购物车里的情况。

cart = Cart()

cart.add(g1)

cart.add(g2,3)

cart.add(g3,2)

print(cart.cart)

for goods in cart.goods_list:

print(goods.id,goods.name,cart.cart[goods.id],goods.price*cart.cart[goods.id]*goods.discount)

def get_total_amount(self):

"""获取当前购物车中的总价"""

amount = 0

for id,num in self.cart.items():

for goods in cart.goods_list:

if id == goods.id:

amount += goods.price * num

return amount

def get_pay_amount(self):

"""获取实际需要支付的总价"""

payamount = 0

for id, num in self.cart.items():

for goods in cart.goods_list:

if id == goods.id:

payamount += goods.cal_price() * num

return payamount

上面有重复代码,注意多次使用的代码定义成函数,函数的作用就是消除重复代码。上面代码可修改为:

def goods_by_id(self, id):

'''根据商品ID找到商品'''

for goods in cart.goods_list:

if id == goods.id:

return goods

def get_total_amount(self):

"""获取当前购物车中的总价"""

amount = 0

for id,num in self.cart.items():

goods = self.goods_by_id(id)

amount += goods.price * num

return amount

def get_pay_amount(self):

"""获取实际需要支付的总价"""

payamount = 0

for id, num in self.cart.items():

goods = self.goods_by_id(id)

payamount += goods.cal_price() * num

return payamount

展示商品信息:

def show(self):

"""显示当前购物车中所有商品的数量、价格,以及总价"""

print('商品id','\t','商品名称','\t','商品数量','\t','商品总价')

for id,num in self.cart.items():

goods = self.goods_by_id(id)

print(id,'\t',goods.name,'\t',num,'\t',goods.price*num)

total_amount = self.get_total_amount()

pay_amount = self.get_pay_amount()

print('总金额:',total_amount,'\n支付总金额:',pay_amount)

cart.show()

显示为:

为了格式对齐,改进代码如下:

def show(self):

"""显示当前购物车中所有商品的数量、价格,以及总价"""

title = ('商品id','商品名称','商品单价','商品数量','商品总价')

def show_row(row):

"""内部定义函数,显示购物车中的一行"""

for col in row:

print(str(col).ljust(12),end='\t')

print()

print("-" * 70)

show_row(title)

for id,num in self.cart.items():

goods = self.goods_by_id(id)

price = '%.2f' % goods.price

if goods.discount < 1:

price = '%.2f(%.d折)' % (goods.price,goods.discount*10)

show_row((id, goods.name, price, num, '%.2f' %(goods.cal_price()*num)))

total_amount = self.get_total_amount()

pay_amount = self.get_pay_amount()

discount_amount = total_amount - pay_amount

show_row(('', '', '', '', '商品总金额:%.2f' % total_amount))

if discount_amount > 0:

show_row(('', '', '','','优惠总金额:%.2f' % discount_amount))

show_row(('', '', '', '','支付总金额:%.2f' % pay_amount))

cart.show()

显示如下:

可以继续增加或者删除,并随时可以查看购物车的商品、计算总金额。如果商品的数量为零,则会从购物车中被删除

cart.remove(g2, 2)

cart.show()

cart.remove(g2, 1)

cart.show()

如果商品的名称、价格或者折扣发生了变化,我们只需要修改商品对象就可以了,其他的代码都不用修改,购物车中的信息会实时的跟随调整。

cart.add(g3)

cart.show()

g3.name = '华为P40 pro'

cart.show()

可以看到,在修改了g3对象的商品名称之后,再次显示购物车时发生了变化 ,而我们的Cart类不用修改任何代码,这样做到了不同实体之间的操作隔离

3 模块和包管理

Python中具有丰富的标准库和第三方库,学习并掌握模块、包的概念尤为重要,决定了是否能够利用这些丰富的资源,以及如何妥善组织好自己的代码。

3.1 模块的导入

首先,来导入一个内置模块

import math

math是Python标准库中的一个模块,用来进行数学运算,在上面使用 import 关键字将它导入了,就可以使用它的功能啦。

# 求一个数的平方根

math.sqrt(4)

现在我们可以使用math模块里的所有函数了,可以使用dir来看一下都有哪些函数

dir(math)

也可以使用from ... import ... 这种语句来具体导入某一个子模块或函数

from math import sqrt

sqrt(4)

这种方式更精确的导入某个函数,使用起来更方便, 但要注意重名的问题。如果说我们的代码本来就有一个叫sqrt的函数,那我们可以使用 as 关键字来给模块起一个别名

from math import sqrt as squarte

def sqrt(num):

pass

squarte(4) # 2

或者是这样:

import math as math2

math = 0

math2.sqrt(4) # 2

有时候需要一次性导入多个模块,可以这样写

import sys, os

from math import sqrt, pow

注意,在实际调用模块之前,必须先导入,否则将会产生报错。

# 将会产生NameError

math.sqrt(4)

import math

如果导入一个不存在的模块,也会产生报错

# 将会产生ModuleNotFoundError: No module named 'maht'

import maht

3.2 自定义模块

除了使用标准库的模块,我们也可以自己定义模块,实际上,这也是我们在项目中组织代码的基本方式。以上一个综合案例“电商购物车”为例,实际的文件结构应该是这样的:

└── project

├── cart.py # Cart类

├── goods.py # Goods类

└── main.py # 入口文件

shopcart目录里面,有三个文件,不同的类写在不同的文件内,cart.py和goods.py文件和原来保持一致即可。我们来看看main.py

from cart import Cart

from cart import * 全部导入

from goods import Goods

g1 = Goods('iPhone 11', 6000, 0.9)

g2 = Goods('U盘32G', 100, 0.8)

g3 = Goods('华为P40', 5000)

cart = Cart()

cart.add(g1)

cart.add(g2, 3)

cart.show()

main.py作为项目的入口文件,我们实际运行的时候就是从它启动

python main.py

那Python解释器是怎么找到cart和goods模块的呢?因为它们和main.py在同一个目录下,所以可以自动的发现它们。那如果有很多这样的模块,我们想把它们放到同一个目录下,以便统一管理,该怎么做呢? 比如,需要将cart.py 和 goods.py放到shopcart包内,调整目录结构如下:

├── project

│ ├── main.py

│ └── shopcart

│ ├── __init__.py

│ ├── cart.py

│ └── goods.py

如果发现目录内有名为 pycache 的文件夹,那是Python在导入时自动生成的缓存文件,可以忽略。

在mian.py同级目录下,多了一个shopcart目录,注意,shopcart目录里除了cart.py和goods.py目录,还多了一个 __init_.py ,这是一个空文件,它的文件名看起来很奇怪,这是Python规定的命名规范,只要目录有一个名为 __init_.py的文件,则将这个目录视为(package),现在修改main.py,作一下调整:

from shopcart.cart import Cart

from shopcart.goods import Goods

同时将下面的部分也做一下调整

if __name__ == '__main__':

g1 = Goods('iPhone 11', 6000, 0.9)

g2 = Goods('U盘32G', 100, 0.8)

g3 = Goods('华为P40', 5000)

cart = Cart()

cart.add(g1)

cart.add(g2, 3)

cart.show()

__name__ 表示当前文件所在模块的名称,模块可以通过检查自己的__name__来得知是否运行在main 作用域中,这使得模块可以在作为脚本运行时条件性地执行一些代码,而在被 import 时不会执行。

3.3 常用内置模块

除了上面使用过的math模块以外,Python还有大概100多个内置模块,下面来介绍一下常用的几个模块。

datetime - 日期时间类型

datetime模块中包含了几个常用的日期时间类,其中最常用的是datetime和timedelta。

注意,我们在下面使用的datetime是指datetime类而不是datetime模块。

from datetime import datetime, timedelta

# 返回当前时间的datetime对象

now = datetime.now()

type(now)

# 查看当前时间的年、月、日

print(now.year, now.month, now.day)

# 查看当前时间的时间戳,精确到微秒

now.timestamp()

print(datetime.now().timestamp())

计算机中时间的起始点都是1970年1月1日00:00:00,时间戳就是从1970年1月1日00:00:00到现在总秒数。所以如果时间戳A比时间戳B的值小,说明A在B之前。

datetime也提供将日期时间对象和字符串相互转换的操作,这在处理数据时会经常使用。

# 返回指定格式的日期字符串

datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 2020-08-10 20:29:41

datetime.now().strftime('%H:%M:%S %Y/%m/%d')) # 20:30:50 2020/11/29

# 将指定格式的字符串转换为日期时间对象

datetime.strptime('2020-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')

%Y这种形式是日期时间的格式代码,下面是一些常用的代码含义:

还有很多格式,可以查看Python官方文档:

只要得到了datetime对象,我们就可以把它转换成各种格式。同样,只要有一个相对标准化的格式,我们就可以将它转换为datetime对象。

得到datetime对象后,可以对它进行修改,显示去年的今天现在这个时候的时间

now = datetime.now()

last_year = now.replace(year=2019)

print(last_year.strftime('%Y-%m-%d %H:%M:%S'))

如果想知道两个datetime对象之间相差多长时间,可以将这两个对象相减,得到的对象就是一个timedelta对象,我们可以根据timedelta对象知道这两个时间相差多少天多少分多少秒。

delta = now - last_year

print(delta) #366 days, 0:00:00

print(type(delta)) #

print(delta.days, delta.seconds) #366 0

现在得到delta就是一个timedelta对象, 它表示366天整的时间,我们也可以将一个datetime对象和一个timedelta对象相加,将会得到一个新的datetime对象. 将当前时间加上366天,就是明年的明天。

timedalte 是datetime中的一个对象,该对象表示两个时间的差值

构造函数:datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) 其中参数都是可选,默认值为0

timedelta类提供了非常便捷的方式帮我们处理日期时间:

from datetime import timedelta

# 明年的今天

print(now + delta) #2021-11-30 20:56:14.603773

# 20天以后的时间

print(now + timedelta(days=20)) #2020-12-19 20:56:14.603773

# 两个半小时之前的时间

print(now - timedelta(hours=2, minutes=30)) #2020-11-29 18:26:14.603773

3.3.2 time - 时间的访问和转换

还有一个经常使用的时间模块time

import time

# 返回当前时间戳

time.time() #1606654855.7623074

# 返回当前时间的格式化字符串

time.strftime('%Y-%m-%d %H:%M:%S') #2020-11-29 21:00:55

其实time模块的另一个函数我们也经常使用,它可以使我们的程序暂时睡一会儿

print("好累呀,我要小睡3秒钟")

time.sleep(3)

print("好啦,我又元气满满!")

sleep函数会将当前的程序暂停若干秒数。

3.3.3 random - 生成随机数

准确的说是生成伪随机数,这是一个数学问题。默认random模块会根据当前的系统时间作为随机数种子,所以可以保证生成的随机数不会重复。

import random

# 生成一个随机浮点数,范围[0.0, 1.0)

random.random()

# 生成1到100之间的随机整数,包括1和100

random.randint(1, 100)

# 从序列中随机抽出一个元素

az=[chr(i) for i in range(65, 65 + 26)]

random.chioce(az)

random.choice(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

# 从序列中随机抽出k个元素,注意抽出来的元素可能会重复

random.choices(['a', 'b', 'c', 'd', 'e', 'f', 'g'], k=2)

>>> random.choice(az)

'N'

>>> ''.join(random.choices(az,k=3))

'QON'

>>> '-'.join(random.choices(az,k=3))

'J-S-K'

# 跟choices函数类似,但它是不重复的随机抽样

random.sample(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

# 将一个序列随机打乱,注意这个序列不能是只读的

lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

random.shuffle(lst)

3.3.4 os - 操作系统接口

os模块提供了一种使用与操作系统相关的功能的便捷式途径。需要大家了解一些操作系统的知识。

# 获取当前的工作目录

print(os.getcwd())

# 创建目录,只能创建一层目录

os.mkdir(os.getcwd() + '/test')

os.mkdir(os.getcwd() + '/abc')

# 创建多层目录

os.makedirs(os.getcwd() + '/def/123')

# 返回一个列表,该列表包含了 path 中所有文件与目录的名称

os.listdir(os.getcwd())

# 返回一个列表,该列表包含了根目录中所有文件与目录的名称

os.listdir('/')

另一个很常用的子模块就是os.path,它提供了常用的路径操作。

# 显示当前目录的绝对路径

os.path.abspath('./')

os.path.abspath("__file__")在大部分操作系统中,一般用 . 表示当前目录,用 .. 表示父级目录

相对路径:相对于当前目录的路径

绝对路径:以根目录为开始的路径(windows和Mac、Linux的根目录不同)

目录分隔符:windows 是 \ , Mac 和 Linux中是 /

# .表示当前目录,..表示父级目录

print(os.path.abspath('..'))

# 相对路径 ./text.txt ../test/abc.py

# 绝对路径 /Users/xxx/projects c:\documents\readme.txt

# 目录分隔符: Windows: \ Mac和Linux /

cur_file = os.path.abspath(__file__)

# 判断“文件“是否存在

print(os.path.isfile(cur_file)) #True

print(os.path.isfile('/Users/xxx/projects')) #False

# 输出当前系统下的目录分隔符

print(os.sep) #\

# 多个路径拼到一起

print(os.path.join(os.getcwd(), 'def', '123'))

print(os.path.dirname(cur_file))

print(os.path.basename(cur_file))

print(os.path.basename('/tmp/test'))

# 如果 path 是 现有的 目录,则返回 True。

os.path.isdir(path)

# 如果 path 是 现有的 常规文件,则返回 True。

os.path.isfile()

# 目录分隔符

os.sep

# 合理地拼接一个或多个路径部分。

os.path.join(path, *paths)

# 返回路径 path 的目录名称

os.path.dirname("/tmp/test.txt") # '/tmp'

# 返回路径 path 的基本名称,文件名或是最后一级的目录名

os.path.basename("/tmp/test.txt") # 'test.txt'

os.path.basename("/tmp/test") # 'test'

(未完待续)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值