前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python基础学习(二)

Python基础学习(二)

作者头像
py3study
发布2020-01-17 12:10:59
6680
发布2020-01-17 12:10:59
举报
文章被收录于专栏:python3python3

Python函数总结

一、函数的基本用法
1、概念:

函数是对程序逻辑进行结构化或是过程化的一种编程方法,其是组织好的,可重复使用的,用来实现单一,或者相同功能的代码段。

函数提高了应用点的模块性和代码的重复利用率

本质:函数是对功能的封装

形式参数:简称形参,本质是一个没有值的变量 ​ 实际参数:简称实参,本质是常量,变量或者表达式 ​ 传参:实参给形参赋值的过程

而实参的类型取决于形参的需要

2、函数定义:
代码语言:javascript
复制
  def  函数名(参数1,参数2,参数3.。。。):
          函数体
          return 返回值

注:a、函数命名遵循标识符规则,做到见名知意,小驼峰命名法、

b、参数1,参数2,参数3.....形式参数,不同的参数之间使用逗号隔开,参数的数量没有限制,依据具体的需求决定参数的数量

c、函数体:被封装的功能

d、return:结束函数,将返回值返回给调用者,也可单独使用

e、返回值可为常量、变量、表达式

3、返回值

返回值:表示一个函数执行完毕之后得到的结果

注:对于return语句不带参数,则返回一个None

4、调用

函数的调用:实质就是函数入栈出栈的过程

即:函数的入栈:函数被调用;函数的出栈:函数被调用完毕

注:在函数调用的过程要注意避免出现死循环

5、变量的作用域

变量的作用域:指变量可以被访问的范围

作用域的划分:

L:(local)局部作用域

E:(Enclosing)函数作用域(闭包)

G:(Global)全局作用域

B:(Built-in)内置作用域

变量的查找规则(变量重名):

python中变量的作用域由大到小,依次为内建(built_in B) >全局(glbal G)> 函数的闭包外(enclosing E)> 局部(local L)

注:在变量重名情况下在函数内部访问变量时使用就近原则。

如果将全局变量的名字声明在一个函数体内的时候,全局变量的名字能被局部变量给覆盖掉,此时我们就需要使用global或者nonlocal来声明变量了。

代码语言:javascript
复制
  #1.变量不重名
  num1 = 10    #全局作用域
  ​
  def outer():
      num2 = 20    #函数作用域
      def inner():
          num3 = 30  #局部作用域
          print(num1,num2,num3)
      return inner
  ​
  f = outer()
  f()
代码语言:javascript
复制
  # global:全局的
  # 全局变量
  num1 = 4
  def func1():
     # 声明num1是全局变量的num1
      global  num1
      print(num1)   #4
   
  num1 = 20
  func1()
  ​
  a = 10
  def test():
      global  a
      a = a + 1
      print(a)   #UnboundLocalError: local variable 'a' referenced before assignment
      
  test()
  ​
  ​
  # nonlocal:不是局部的
  # nonlocal;前提条件:必须使用在闭包中
  x = 0  # 全局作用域
  def outer():
      x = 1       # 函数作用域
      def inner():
         # 将一个局部作用域的变量声明为不是局部的,局部----》函数
          nonlocal x
          x = 2   #局部作用域
          print("inner:",x)
          
  #在外部函数中调用内部函数
  nner()
  print("outer:",x)
  outer()
  print("global:",x)
6、参数

1、参数的传递:

参数的传递有值传递和引用传递

值传递:传递不可变类型的数据,例:num、string、tuple等;在值传递时,形参的改变并不会影响实参

引用传递:传递可变类型的数据,例:list、dict、set等;形参的改变会影响实参的使用

在函数中参数传递的是对象的引用

代码语言:javascript
复制
  #引用传递:传递列表或者字典时,如果改变引用的值,就修改了原始的对象
  def check(l):
          print(l)
          print(id(l))
          l.append([1, 23, 2, 3, 4])
          return l
      
  l = [1, 2, 3, 4]
  print(check(l))
  print(id(l))
  ​
  '''
  [1, 2, 3, 4]
  2902500909320
  [1, 2, 3, 4, [1, 23, 2, 3, 4]]
  2902500909320
  '''
  #值传递:当传递不可变对象时,如果改变引用变量的值,只是创建了不同的对象,原始对象并没有改变。
  ​
  def check(s):
      print(s)
      print(id(s))
      s = "i am test"
      print(id(s))
      return s
  ​
  s = "This is a test"
  print(check(s))
  print(s)
  ​
  '''
  This is a test
  2418424029424
  2418424029488
  i am test
  This is a test
  ​
  ​

2、参数的类型:

a、必须参数:必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

代码语言:javascript
复制
  def printme( str ):
     "打印任何传入的字符串"
      print str
      return
   
  #调用printme函数
  printme()

b、关键字参数:允许实参的顺序和形参的顺序不一致,因为Python解释器会根据关键字参数的名称自动的匹配

代码语言:javascript
复制
  def show2(name,age):
      print("name:%s age:%d" % (name,age))
  ​
  show2(name="jack",age=47)
  # 注:关键字参数使用在实参列表中,不要求顺序保持一致
  show2(age=36,name="fadj")
  # 注:在实参列表中,可以不全部设置为关键字参数
  show2("zhangsan",age=15)
  ​
  # 注:关键字参数只能出现在实参列表的后面
  def show3(a,b,c):
      print(a,b,c)
  ​
  show3(1,4,4)
  show3(a=3,c=5,b=5)
  show3(45,b=9,c=18)
  #show3(a=45,9,18)  #SyntaxError: positional argument follows keyword argument

c、默认参数:调用函数的时候,如果没有传递参数,则使用默认值【default】

代码语言:javascript
复制
  #注意1:默认参数体现在形参列表中
  def func3(name="abc",age=18):
   print("name:%s age:%d" % (name, age))
  #注意2:使用了默认参数,则可以选择不传参,使用的默认值,如果传参,则相当于给形参重新赋值
  func3()
  func3("jack",19)
  #注意3:关键字参数和默认参数可以结合使用
  func3(name="jack",age=19)
  func3("jack",age=19)
  ​
  #注意4:形参列表可以不全部设置为默认参数,只要吃部分设置,则默认参数出现在形参列表的后面
  #报错:SyntaxError: non-default argument follows default argument
  # def show4(name="abc",age):
  #     print("name:%s age:%d" % (name, age))
  # show4("bob",18)
  ​
  print("hello")

d、不定长参数:可以处理比声明时更多的参数

代码语言:javascript
复制
  #a.*,一般写法为*args
  def text1(*num):
      print(num)
      for n in num:
          print(n)
          
  # *不定长参数被当做元组处理,num形参名其实就是元组名
  text1(10)
  text1(10,4,54,65,65,7)
  # 可以传一个元组,但是,元组被当做一个整体全部传参
  text1((54,4,64))
  ​
  # 一般情况下,将不定长参数设置在形参列表的最后
  def text2(*num3,num1,num2):
      print(num1,num2,num3)
  ​
  # 如果不定长参数出现在形参列表的前面或者中间,则可以借助于关键字参数传参
  #text2(12,43,43)
  text2(12,34,num1=35,num2=59)
  ​
  # 在形参列表,不定长参数最好只出现一个
  #错误演示
  # def text3(*num3,num2,*num1):
  #     print(num1,num2,num3)
  # text3(43,53,num2=10,5,5,4)
  ​
  ​
  #b.**,一般写法为**kwargs
  def text4(**num3):
   print(num3)
  ​
  #注意1:**,被当做字典处理,传参的时候,需要以key=value的方式进行传参
  text4(x=26,y=17)
  ​
  #注意2:在形参列表中使用**,保证出现在后面
  ​
  """
  使用场景:单例设计模式
  def text(*args,**kwargs):
  ​
  总结:
  a.必需参数使用最多,其次是不定长参数
  b.关键字参数和默认参数最多使用在系统函数中
  """
7、匿名函数

lambda表达式:python中的匿名函数主要用来处理一些简单逻辑表达式的封装,使用lambda关键字

优点:不占用内存,提高代码的运行速度

一般格式为:

代码语言:javascript
复制
var = lambda args:表达式

例如:

代码语言:javascript
复制
f = lambda x,y:x+y
#该函数的调用结果为 冒号后的表达式所表达的结果
print(f(1,2))
二、函数进阶
1、概念【特殊用法】:

1、变量可以指向函数

代码语言:javascript
复制
x = abs(-35)
print(x)   # 35

# 一个普通的变量可以指向一个函数,该变量就可以被当做函数调用
f = abs
print(f)
print(f(-100))

def check():
 	print("check")

check()
f1 = check
f1()

2、函数也可以作为变量名

代码语言:javascript
复制
# 本质:函数名就是一个指向函数的变量
print(abs(-28))
# abs = "hello"
# print(abs(-7))

3、函数作为参数使用

代码语言:javascript
复制
# 调用形参中的函数,必须和原函数保持一致【注意是否需要传递参数】
def test(a,b,fun):
 	return fun(a) + fun(b)   #abs(43) + abs(-27)
print(test(43,-27,abs))  #fun = abs

def test1(s1,s2,func):
 	return func(s1) + func(s2)
print(test1("hello","gajghj",len))
2、闭包:

在函数内部定义了另一个函数,即存在外部函数和内部函数

闭包【closure】:在外部函数中定义一个内部函数,并且外部函数的返回值是内部函数的引用。

代码语言:javascript
复制
# 普通函数
def show():
    print("1111")
 	return  num1

# 闭包
def outter():
 	def inner():
     	print("inner")
 	return inner

f = outter()   #f = inner
f()

# 在闭包设置参数,a和b两个变量被称为自由变量【临时变量】
# 闭包的优点:在外部函数中定义的变量,在内部函数可以直接访问
def outer1(a):
 	b = 10
	def inner1():
     	print(a + b)
	return inner1

f1 = outer1(23)  #f1 = inner1
f1()


# 内部函数设置参数
def outer2(a):
 	b = 10
 	def inner2(c):
     	print(a + b + c)
	return inner2

f2 = outer2(23)
f2(12)
3、装饰器:

装饰器【Decorator】:使其他函数在不需要做任何代码的变动下,为函数添加功能,装饰器的返回值也是一个函数。

本质:装饰器的本质就是一个闭包,其作用是将一个函数作为参数,返回另一个函数

装饰器函数运行在函数定义的时候 装饰器需要返回一个可执行的对象 装饰器返回的可执行对象要兼容函数f的参数

代码语言:javascript
复制
import  time
#1.简单的装饰器
def test():
 	print("hello")
# func就是需要被装饰的函数
def outer(func):
 	def inner():
     	# 增加新功能
    	print("new~~~~")
     	# 调用原函数
    	func()
 	return  inner

f1 = outer(test)
f1()

# 练习:书写装饰器,计算test函数执行的时间
def outer(func):
 	def inner():
     	t1 = time.time()
        func()
		t2 = time.time()
		print(t2 - t1)
	return  inner
f1 = outer(test)
f1()

#2.带有参数的装饰器
def getAge(age):
 	print(age)
# getAge(10)
# getAge(-36)
# 注意:被装饰的函数有参数,inner不一定需要设置参数,只有当需要在inner内部对参数进行操作的时候,则需要同步
def wrapper1(func):
 	def inner(a):
     #数据的校验
     	if a < 0:
         	a = -a
        func(a)
 	return  inner

f = wrapper1(getAge)
f(10)
f(-36)


# 使用装饰器语法糖
# 注意:使用@,必须保证装饰器存在的情况下,才能给函数增加功能
def wrapper2(func):
 	def inner(a):
     	# 数据的校验
     	if a < 0:
         	a = -a
		 func(a)
	return inner

@wrapper2
def getAge1(age):
 	print(age)
    
getAge1(-19)

# 参数为不定长参数的装饰器
# 使用场景:一个装饰器可以同时作用于多个不同函数的情况
def wrapper3(func):
 	def inner(*args,**kwargs):
     	# 新增的功能
     	print("abc")
     #调用原函数
     	func(*args,**kwargs)
 	return  inner

@wrapper3
def test(a,b):
     print(a,b)

test(10,20)

@wrapper3
def test1():
 print("gsjrg")

test1()

# 多个装饰器作用于同一个函数
def wrapper11(func):
 	def inner(*args,**kwargs):
     	# 新增的功能
     	print("装饰器~~~~11")
     	# 调用原函数
     	func(*args,**kwargs)
 	return  inner

def wrapper22(func):
 	def inner(*args,**kwargs):
     	# 新增的功能
     	print("装饰器~~~~22")
     	# 调用原函数
     	func(*args,**kwargs)
 	return  inner

@wrapper11    # func:check
@wrapper22      # func:被wrapper11装饰之后的函数
def check():
 	print("check")

check()
#总结:多个装饰器作用于同一个函数的时候,从上往下依次执行,但是,原函数只被调用一次
4、偏函数

通过设定默认参数,可以降低调用的难度,偏函数也可以起到这样的作用

概念:对函数的参数做一些控制的函数

注意:偏函数一般不需要自己定义,直接使用【functools模块其中提供了偏函数的使用】

代码语言:javascript
复制
import  functools


print(int("23534"))
# print(int("abc345"))  #ValueError: invalid literal for int() with base 10: 'abc345'

# 在int中有一个默认参数base,用来指明当前数据的进制
print(int("110"))
print(int("110",base=10))
print(int("1010",base=2))
print(int("1010",2))
# 自定义一个函数,设置一个默认参数base,默认值设置为2
def int2(x,base=2):
 	return int(x,base)

print(int2("1010"))
print(int2("1010",10))

# 系统的functools模块中提供了偏函数的实现
# 参数:已经存在的函数名   默认参数
int3 = functools.partial(int,base=2)
print(int3("1110"))
print(int3("1110",base=10))

# 思想:根据一个已经存在的函数,通过修改该函数参数的默认值,生成一个新的函数,被称为偏函数
三、高阶函数

1、filter():过滤

代码语言:javascript
复制
"""
filter(function,iterable)  通过一定的条件过滤可迭代对象中的元素

工作原理:把传入的函数依次作用于可迭代对象的每一个元素,根据返回的布尔值【True或者False】决定是否保留元素
如果返回True,则表示需要保留该元素;如果返回False,则表示需要过滤掉该元素
"""
# 将列表中的偶数筛选出来
list1 = [1,2,3,4,5,6,7,8]
# 自定义【追加】
newList1 = []
for num in list1:
 	if num % 2 == 0:
    	 newList1.append(num)
print(newList1)
# 自定义【删除】
newList2 = list1.copy()
for num in newList2:
  	if num % 2 == 1:
     	newList2.remove(num)
print(newList2)

#方式三:列表生成式
newList3 = [num for num in list1 if num % 2 == 0]
print(newList3)

# filter
def func(num):
	# 保留偶数元素
 	if num % 2 == 0:
     	return True
	# 过滤奇数元素
 	return False

newList4 = list(filter(func,list1))
print(newList4)

# 将爱好为"无"的数据剔除掉
data = [['姓名', '爱好', '年龄'],['tom', '无', 10],['jack', '唱歌', 28]]
def func2(s):
 	if s == "无":
     	return False
	 return  True
for line in data:
  	result = list(filter(func2,line))
  	print(result)

2、map():映射

代码语言:javascript
复制
"""
map(function,Iterable)  会根据的函数对指定的序列做出映射
function:函数
iterable:可迭代对象,序列
工作原理:函数会以序列中的每一个元素作为参数,返回包含函数的功能的新列表
功能:将传入的函数依次作用于序列中的每一个元素,并把结果作为新的iterable返回
"""
# 计算列表中各个元素的平方
list1 = [1,2,3,4,5]
# 自定义
newList1 = []
for num in list1:
 	newList1.append(num ** 2)
print(newList1)

# 列表生成式
newList2 = [num ** 2 for num in list1]
print(newList2)

# 生成器
newList3 = list((num ** 2 for num in list1))
print(newList3)

# map[def定义的函数]
def func(x):
  return  x ** 2

result = map(func,list1)
print(result)
print(type(result))
newList4 = list(result)
print(newList4)

"""
传给map的函数的要求:
 a.参数只能有一个【默认将可迭代对象的一个元素传递给该函数】
 b.该函数必须有返回值,否则得到的可迭代对象中的元素为None
"""
#方式五:map[匿名函数]
newList5 = list(map(lambda x:x ** 2,list1))
print(newList5)

# 已知有一个整数列表,将转换为字符串列表
#例如:[2,3,4,5]------>['2','3','4','5']   str()
list2 = [2,3,4,5]
newL1 = []
for num in list2:
 	newL1.append(str(num))
print(newL1)
newL2 = [str(num) for num in list2]
newL3 = list((str(num) for num in list2))
newL4 = list(map(str,list2))
print(newL4)

reduce():迭代【累积】

代码语言:javascript
复制
from functools import reduce
"""
导入模块:functools
reduce(function,iterable):函数会对序列中的元素进行累积
功能:用传给reduce的函数先序列中的第1,2个元素进行操作,
用得到的结果和第3个元素进行操作,用得到的结果和第4个元素进行操作。。。。

举例:
f,[a,b,c,d]
reduce(f,[a,b,c,d])
工作原理:f(f(f(a,b),c),d),类似于递归
"""

# 计算一个整数列表中元素的和
# 一:自定义
list1 = [1,2,3,4,5]
total = 0
for num in list1:
 	total += num
print(total)

# 二:reduce【def定义函数】
def mySum(x,y):
 return x + y
result0 = reduce(mySum,list1)
print(result0)
"""
mySum(1,2)---->3
mySum(3,3)---->6
mySum(6,4)---->10
mySum(10,5)---->15
"""

# 三:reduce[匿名函数]
result1 = reduce(lambda x,y:x + y,list1)
print(result1)
"""
函数的注意事项:
 a.必须有两个参数
 b.必须设置返回值【报错:TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'】
"""

# 将[1,3,5,7,9]转换为整数13579
list2 = [1,3,5,7,9]
def func(x,y):
 	return  x * 10 + y

result3 = reduce(func,list2)
print(result3)

# 自定义一个函数,实现str转换为int的函数  int(xx)
def charToNum(s):
 # 自定义字符串和整型之间的映射关系
 	digits = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6}
  return digits[s]

# 需求:“24356”------》24356
# a.产生映射关系
r0 = list(map(charToNum,"24356"))
print(r0)
#b.使用reduce累积
r1 = reduce(func,r0)
print(r1)
print(type(r1))

r2 = reduce(func,map(charToNum,"23456"))
print(r2)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python函数总结
    • 一、函数的基本用法
      • 二、函数进阶
        • 三、高阶函数
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档