n203_python包模块函数

4.包与模块

4.1 包

1.什么是“包”?包与模块的区别是什么?

包是由多个与同一功能相关的模块组成,表现形式为含有“_ _ init _ _.py”的文件夹。

模块是一个python文件,其中可以写类、语句、函数。

模块(module) 通常为 → 一个.py文件
↓ 由模块组成 ↓ 由.py文件组成
包(package) 通常为 → 含有“_ _ init _ _.py”的文件夹
1-文件:物理上的组织方式,如math.py的程序文件可以作为module的文件类型有.py .pyo .pyc .pyd .so .dll
2-包:通常作为一个文件夹,即含有 _ _ init _ _ .py文件的文件夹
3-模块:逻辑上的组织方式,如math
4-库:模块的集合

2.如何进行包的下载、安装、更新、删除?

用包管理器,如pip(python专用包管理器)、conda(支持多种语言的通用包管理器)。

用PIP工具下载某个包很慢,可以使用Conda或者PIP的国内镜像服务器。(搜索PIP国内镜像服务器的URL即可)

PIP仅管理python语言的包,对应的包服务器为PyPI(Python Packages Index),官网:https://pypi.org/
Conda管理多种语言的包,包服务区为Conda,官网:https://conda.io

注意:是要在命令行中(Anaconda Prompt)输入命令。

也可以在Jupyter Lab中进行pip或者conda,但是需要在命令前加上

! pip install jieba

3.在python中使用包的基本步骤

使用pip或者conda下载或者安装所需包之后,导入(import)包中的指定模块,就可以调用指定模块中的函数或类了。

# 1-导入一个模块:as后面使用约定俗成的别称
import pandas as pd
# 2-同时导入多个模块,使用,分隔
import pandas as pd,numpy as np
# 3-只导入一个模块中的特定函数
from pandas import DataFrame
# 4-有层次的文件结构的模块的导入,用.表示层次关系
import Graphics.Primitive.fill

如果使用pip或者conda无法下载或安装某包,可以到改包的官网下载,并按照官网提示直接安装即可。

4.在python中如何调用包管理器pip或者conda?

# 以下操作均在命令行中完成(Anaconda Prompt)
# ①查看已安装的列表
pip list
conda list
# ②下载或安装指定的包
pip install 包名
conda install 包名
# ③更新已安装的包
pip install -upgrade 包名
conda updata 包名
# ④移除已安装的包
pip uninstall 包名
conda uninstall 包名

数据分析中常用的包有:

数据框和Series处理 pandas
多维数组处理 numpy
机器学习 scikit-learn、tensorflow、pytorch
统计可视化 matplotlib
数据可视化 seaborn
统计功能 statsmodels
SQL语句编程 pandsql
Web爬取 scrapy
Spark编程 pySpark
自然语言处理(英文 / 中文) nltk、spacy / pynlpir、Jieba
生成词云 wordclound
生成随机数 random

5.查看包的帮助

①jupyter lab中的help菜单提供了常用包的官网地址。

②查阅特定包的官网地址,搜索URL即可。

③使用每个包提供的内置属性和方法,查看包的版本号。(使用包前先导入,否则会视为未定义的变量,和变量的使用道理一样)

import pandas as pd
pd.__version__  #'1.4.1'

version前后各有两个下划线,此处使用了dunder属性

4.2 模块

1.什么是模块?

模块是一个python文件,其中可以写类、语句和函数。模块与包之间的关系为:

多个模块 + _ _ init _ _.py → 包

2.模块的存在形式是什么?存放在哪里?

模块的存在形式分为内置模块 builtin_function_or_method非内置模块 module 两种存在形式。

  • 非内置模块以.py文件的形式存放在对应包的文件夹下,如可放在Anaconda安装目录的Lib\sit-packages中,与包同名的文件夹中。
  • 为提高性能,python将经常使用的包做成了内置模块,并用C语言编写,内置到解释器中。

3.python模块的使用步骤

先import,后调用其中的函数。

  • 可以导入整个模块,通过模块名或者模块别名使用其方法,此时函数的调用必须使用包名或者别名。

    直接import时调用函数的正确方式:模块名.函数名()

    from 包 import 函数 时可以直接使用函数名

    import math
    import numpy as np
    
    [math.sqrt(i) for i in np.arange(1,10)]
    """
    [1.0,
     1.4142135623730951,
     1.7320508075688772,
     2.0,
     2.23606797749979,
     2.449489742783178,
     2.6457513110645907,
     2.8284271247461903,
     3.0]
    """
    
  • 可以只导入模块中的特定函数,此时函数的调用可以不使用包名或者别名,直接就能使用。

    from numpy import arange
    from cmath import sqrt
    arange(1,10)
    sqrt(-1)
    
  • 查看内置模块的方法:使用sys模块查看内置模块的清单

    import sys
    sys.builtin_module_names
    

5.内置函数、模块函数、自定义函数

5.1 函数

1.python中"函数"与"方法"是一个概念么?

  • 函数:python内置函数

    函数是指类外定义的"函数",可以直接用函数名调用,如sorted(myList)。

  • 方法:对象的方法,比如列表的方法

    方法是指类中定义的"函数",必须通过对象名调用,myList.sort()。

2.python中的函数有几种?

函数主要有三种:内置函数、模块函数、自定义函数。

  • 1-内置函数(Built-In Function,BIF):内置在解释器中的函数,可以直接用函数名调用,如len()、type()、sorted()等。

  • 2-模块函数:定义在(第三方)模块中的函数,先import所属模块,再通过“模块名”或者“模块别称”调用,如:

    import math
    math.sin(1)
    
  • 3-自定义函数:用户自定义的函数,可以根据函数的定义位置和可见范围进行调用,调用方法是“直接用函数名”。

    此外,python也支持面向过程编程,因此用户自定义的函数可以放在类中,也可以放在类外。

3.python中函数编写的注意事项

凡是用于对象的函数都可以用在函数中,如type(abs),abs和type都是函数。
1- * 参数对应的实参是元组
2- ** 参数对应的实参是字典
3- 函数的返回值可以是迭代器、元组、None等,如果函数中没有return语句,则自动返回None。
4- 建议函数中提供DocString(其内容用'''括起来,左边的三个引号后面必须紧跟上文字,否则会被视为多行注释)

python既支持函数式编程(Functional Programming),又支持面向对象编程(Object Oriented Programming),方便不同数据分析和数据科学项目的完成。

  • 通常当调用第三方包来完成自己的数据分析项目时,使用函数式编程更为方便、实用。

  • 但是当开发一个新的第三方包时,建议使用面向对象方法,以便程序代码的可复用和可维护。

    开发自己的第三方扩展包,可以查阅python官网文档How To Package Your Python Code

4.用户自定义的函数

用关键词 def 定义用户自定义函数

def myfunc():  
    print('请输入x')
    x=int(input())
    if(x>0):
        print('你好')
    else:
        pass
myfunc()

在python中,用户自定义的函数可以写成“单行函数”,称为lambda函数。python既支持面向对象编程也支持面向过程编程,因此自定义的函数既可以放在类中,称为“方法”;也可以放在类外,称为“函数”。

5.2 内置函数

1.什么是内置函数?

内置在python解释器中的函数,可以直接通过函数名(不需要提供所属模块或类名的前提下)调用的函数。

2.查看内置函数的说明和帮助

help()函数 或者 ?操作符,如help(len) 或者 len?

3.常用内置函数

内置函数大致可分为:数学函数、类型函数和其他功能函数。

help() 查看帮助
type() 查看类型
id() 查看id
len() 计算长度
isinstance() 判断是否属于特定类型数据
dir() 列出对象的所有属性
power(2,10) 求取2的10次方
round(2.999,2) 小数点后保留两位(以四舍五入的方式,结果为3.0)
range() 快速生成序列
callable() 判断函数可否被调用
bin() 十进制转化为二进制
hex() 十进制转化为16进制

range()的返回值是一个迭代器。迭代器是“惰性计算”的,所以通过强制类型转换函数list()将迭代器的值进行计算并显示。

5.3 模块函数

1.什么是模块函数?

模块函数是指定义在第三方模块中的函数。

2.如何导入并调用模块函数?

与内置函数不同,模块函数定义在第三方提供的包或模块中,其调用必须在“导入模块”的前提下进行,并通过模块名调用。python中模块的导入方法有很多,不同的导入方法对应了不同的函数调用方法。导入模块函数的方法如下:

①import 模块名,再通过模块名读取模块函数 import math math.sin(1)
②import 模块名 as 别名,再通过别名去调取模块函数
③from 模块名 import 函数名,这样可以直接使用函数名

当导入一个模块时,python解释器为加快程序运行速度,会在与该模块同目录中的_ _ PyCache _ _子目录下生成对应的.pyc文件。

3.调用模块函数时应当注意的问题

*参数 与 ** 参数的区别;位置参数与关键词参数的区别;可选参数与必选参数的区别。

5.4 自定义函数

1.如何自定义函数?

使用 def 关键字

注意:python函数的定义中可以嵌套另一个函数的定义,如闭包(closure)。

如果嵌套函数func2()中调用了外围函数中的局部变量(不是全局变量),则称为闭包。

def func1():
    j=0
    print('lin')
    def func2(i):
        print('ok'+str(i)+str(j))
    return func2
func1() #lin <function __main__.func1.<locals>.func2(i)>
func1()(6) #先运行func1(),return func2时运行了func2
#如果没有这个return语句,系统会自动返回None,导致的结果是None(2)
#错误提示为'NoneType' object is not callable
# lin
# ok60

嵌套函数func2()为局部函数,只有在外围函数func1()中可见,即只能在外围函数func1()内调用它。因此,外围函数中return func2的作用是调用嵌套函数func2(),如果没有return func2,那么func2()是不会被执行的,因为没有其他调用它的地方。

  • 函数中的docString

    在定义函数时,可以设置其docString,说明函数的具体功能是什么

    def get_name(msg):
        '''根据用户提示msg,获取用户名,如果输入为空,则默认为lin'''
        name=input(msg) or 'lin'
        return name
    help(get_name)
    '''
    Help on function get_name in module __main__:
    
    get_name(msg)
        根据用户提示msg,获取用户名,如果输入为空,则默认为lin
    '''
    get_name?
    '''
    Signature: get_name(msg)
    Docstring:
    根据用户提示msg,获取用户名,如果输入为空,则默认为lin
        
    File:      c:\users\lin\appdata\local\temp\ipykernel_7268\63129832.py
    Type:      function
    '''
    

2.参数传递是值传递还是地址传递?

都有。python的传值和传址是根据传入参数类型来选择,当实参为可变变量时,采用地址传递;当实参为不可变变量时,采用值传递。

python的值传递和地址传递取决于实参,而不是形参。如果函数收到的是一个可变对象(比如字典、列表)的引用,就能修改对象的原始值——相当于传址。如果函数收到的是一个不可变对象(比如数字、字符、元组)的引用,就不能直接修改原始对象——相当于传值。

3.返回值的指定方法是什么?

一般返回值使用return语句,没有的话则自动返回None。然而,生成器用yield语句返回值。此外,python允许函数的返回值可以是函数名,最具代表性的是“闭包”。

使用return语句指定返回值,函数见到return自动结束:

def fun(i,j=2):
    j=i+1
    return j  # 没有return的话,返回None,但此时后面一句要使用print()函数,否则看不见None
fun(3)   	 # 4

# python函数可以同时返回多个值
def fun1(i,j=2):
    j=i+1
    return i,j # 相当于return (i,j) 因为元组的表示是可以省去括号,只使用逗号分隔符
a,b=fun1(3)
a,b # (3, 4)

4.函数中变量的可见性如何定义或改变?

全局变量:local 局部变量:local 非局部变量:nonlocal

局部变量local 在函数内部定义的变量,仅在函数内可见
全局变量global 将local变量x 改为global变量的方法:加一行global x
非局部变量nonlocal 与global类似,用法和global一样,但是用于内嵌函数
x1=0		    # 这个x1是全局变量
def func1(i):
    x1=i		# 这个x1是local变量
    print(x1)   
func1(2)
print(x1)
'''
2
0
'''

x1=0
def func1(i):
    global x1  # 此后x1就是全局变量,不再是局部变量,脱离函数体后,在函数体中发生的改变会被保留
    x1=i	   # 此时的x1已经是全局变量,所以后面的输出也是传入的实参值6,而不是一开始定义的0
    print(x1)   
func1(6)
print(x1)
'''
6
6
'''

5.python中函数编程应当注意的问题

①在形参中,应当注意必选参数与可选参数。可选参数是指带有默认值的参数,否则为必选参数。

def mufunc(x1,*x2,x3,x4=4,x5=5): 中的x1,x2,x3为必选参数,x4,x5是可选参数。

②在实参中,应注意位置参数和关键词参数。带有参数名的为关键字参数。

def mufunc(1,2,3,x4=4,x5=5): 中的x1,x2,x3为必选参数,x4,x5是关键词参数。

③在形参中,应当注意 * 参数与 * 参数。 二者都是特殊参数 , * 参数对应的实参是元组, ** 参数对应的实参为字典。

④在形参中,凡是出现在带有 *** 参数的后面定义的形式参数叫做“强制命名参数”,应注意强制命名参数。在函数调用时,实参中必须显式地使用**“强制命名参数”的名称,否则会出错。

6.形参与实参

函数定义时的参数称为——形式参数

# 函数定义时的参数称为——形式参数
def func1(x1,*x2,x3,x4=4,x5=5):
    '''
    x4 和 x5 称为可选参数(已给出参数的默认值),未给出默认值的参数就是必选参数  (必选参数,...,可选参数)
    x2 是强制命名参数,因为前面有一个 *
    形参中的 * 参数和 ** 参数分别以元组和字典(键值对)的形式接收不定长的实参
    强制命名的参数必须以"形参=实参"的形式指定实参值
    当实参为可变对象(值可更改:列表、集合、字典),实参与形参间的数值传递称为地址传递;否则为值传递(元组、字符串、数)
    '''
    
	func1(1,2,3,x4,x5):
    '''
    形参中的可选参数可以不指定实参,已指定形参名称的实参称为关键字实参,比如x4,x5
    位置实参,是未指定形参名称的实参,如1,2,3
    (位置实参,...,关键字实参)
    '''
  • 从函数定义的视角,形参分为可选与必选:带有默认值的为可选,调用它时不用给出实参。没有默认值的是必选,对号入座

    def func1(x1,*x2,x3=1):
        print(x1,x2,x3)
    func1(2,3,0,0) # 2 (3, 0, 0) 1 *x2是用来接收不定长参数的形参
    func1(2,3,0)   # 2 (3, 0) 1
    func1(2,3,0,x3=6)  # 2 (3, 0) 6 x3是关键字参数,必须重新定义x3,否则输出可选参数的初始值
    
  • 从函数调用视角,实参分为位置参数和关键字参数(又称为命名参数),判断依据就是一开始是否命名了;所有关键字参数必须在位置参数后面。同时,在函数调用时,当前面出现接收不定长的实参时,后面的可选实参要想修改的话,必须显式地使用参数名,只写个‘变量名’ 不写’=什么‘ 的话解释器会报变量未定义的命名错误。NameError: name 'x3' is not defined

7.值传递和地址传递

1-值传递:当实参为不可变对象时(int,float,bool,str,tuple),实参和形参分别占用不同的内存空间,在"被调用函数"中修改形参的值,不会影响实参的值。

2-地址传递:当实参为可变对象时(list,set,dict),实参和形参共享一个内存空间,当形参发生变化时,实参也会改变。

实参和形参的数据传递原则是对号入座,除了self、cls等特殊参数,这些特殊参数不需要另外传给实参,如:

# def class_func(cls): 
# def __init__(self,name,age):

注意:

①形式参数分为位置参数和关键字参数,区别在于是否带有默认值,若有,则为关键字参数。

关键字参数必须在位置参数后面,否则会报语法错误,SyntaxError: non-default argument follows default argument,关键字参数(default argument 默认参数)后面不能再出现位置参数(non-default argument 非默认参数)。

②当python的自定义函数中没有写return语句时,python解释器将会自动返回None

8.lambda函数

  • lambda函数是自定义函数的一种,专指使用关键字lambda定义的无名短函数。本质是单行匿名函数
  • lambda 函数 形式参数 : 函数返回值
  • lambda函数的作用:
    • 写表达式时,可以作为表达式的一部分
    • 调用函数时,可以作为实际参数使用。即lambda函数通常以另一个函数的参数形式使用
mylist=[0,1,2,3,4,5,6,7,8,9,10]
# filter(lambda x:x%2==0,mylist) # <filter at 0x14a168a3310> 此时的filter()函数返回值是一个迭代器
res=filter(lambda x:x%2==0,mylist)
list(res) # [0, 2, 4, 6, 8, 10]

filter函数采用迭代式读取方式,从第二个参数mylist中读取满足函数返回值条件的元素,并将其读入第一个参数(lambda 函数)的x中。

posted @ 2022-12-05 09:23  努力生活的小林  阅读(88)  评论(0)    收藏  举报