热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python:流程控制,函数方法

1,顺序结构顺序结构是一种最简单的算法结构,算法中列出的操作步骤是顺序执行的,操作的排列顺序与执行顺序一致,每个操作能且仅能

1,顺序结构


顺序结构是一种最简单的算法结构,算法中列出的操作步骤是顺序执行的,操作的排列顺序与执行顺序一致,每个操作能且仅能被执行一次。

a = "Hello Python"
print(a)
=================
Hello Python


1.1,赋值语句


赋值语句是顺序结构中最常见的语句形式,用于给某个对象赋值。Python中的赋值语句有多种形式,如普通赋值、增量赋值、链式赋值和多重赋值,基本的赋值操作使用最广,其他集中赋值操作使用频率也较高。

# 普通赋值
a = "Hello Python"
# 增量赋值
a += "and Hello World"
# 链式赋值
a = b = c = "燕双嘤"
# 多重赋值
a, b = "燕双嘤", "杜马"

多重赋值的本质是:序列封包和序列解包。


1.2,输入输出


输入:在Python中,用户可以使用input()函数从标准输入设备输入数据。input()函数的一般语法为:

x = input(["输入提示"])

有时需要使用int()和float()等函数将获得的输入数据转换成需要的类型。

a = int(input("请输入一个数:"))

在input()函数的使用中,还可以利用eval()函数将输入的字符串当成有效的Python表达式来求值。

a = eval(input("请输入表达式:"))
print(a)
===========================
请输入表达式:10*12*13*55*88464
7590211200

如果要输入一组数据或一个复杂的数据对象,通常利用input()函数结合eval()函数实现。

a, b, c = eval(input("请输入(a,b,c)"))
print(a, b, c)
a = eval(input("请输入列表"))
print(a)
a = eval(input("请输入元组"))
print(a)
=======================================
请输入(a,b,c)1,2,3
1 2 3
请输入列表[1,2,3,4,5,6]
[1, 2, 3, 4, 5, 6]
请输入元组1,2,3
(1, 2, 3)


输出:在Python中,使用print()函数将数据输出到标准输出设备。print()函数的一般语法形式为:

print(对象1, 对象2, 对象3, 对象4, 对象n,sep="", end="\n")

输出时用参数sep表示输出对象之间的分隔符,默认为空格;参数end的默认值为“\n”,表示print()函数输出完成后自动换行。

print(1, 2, 3)
print(1, 2, 3, sep="***", end="///")
====================================
1 2 3
1***2***3///

格式化输出:Python:简介、变量、字符串、运算符_燕双嘤-CSDN博客


2,选择结构


2.1,if语句


if分支使用布尔表达式或布尔值作为分支条件来进行分支控制。

#第一种形式
if expression:statement...
#第二种形式
if expression:statement...
else:statement...
#第三种形式
if expression:statement...
elif expression:statement...
elif expression:statement...


注意:Python是一门很独特的语言,它的代码是通过缩进来标记的,具有相同缩进的多行代码属于同一个代码块。如果代码莫名其妙地乱缩进,Python解释器会报错。

如果忘记缩进,就不是代码块:

age = 22
if age >20:print(age)
print("你已经是叔叔了")

如果随意缩进,将会报错:

age = 22
if age >20:print(age)print("你已经是叔叔了")


2.2,if条件的类型


Python执行if语句时,会判断if条件是True还是False。但实际上,if条件可以是任意类型,当下面的值作为bool表达式、空字典等都会被当作False处理。

False、None、0、""、()、[]、{}

除了False本身,各种代表“空”的None、空字符串、空元祖、空列表、空字典都会被当成False处理。

s = ""
if s:print("s不为空")
else:print("s不能为空")


2.3,pass语句


Python的pass语句就是空语句,pass在Python中不会被执行的语句,pass语句一般作为占位符或者创建占位程序。在复杂的语句中,如果一个地方需要暂时被留白,那么就使用pass语句。通过使用pass语句,可以让程序更完整。

s = "1"
if s:pass
else:print("s不能为空")


2.4,断言


断言语句和if分支有点类似,它用于对一个bool表达式进行断言,如果该bool表达式为True,该程序可以继续向下执行;否则程序会引发AssertionError错误。

a = input("年龄:")
a = int(a)
assert 20 print("年龄正常")
==================
年龄:1
Traceback (most recent call last):File "E:/Pycharm/WorkSpace/Study/main.py", line 3, in assert 20
AssertionError


3,循环结构


3.1,while循环


while循环的语法格式如下:

[init_statements]
while test_expression:body_statements[iteration_statements]

while语句是先判断再执行,所以循环体有可能一次也不执行。

如果循环条件为True,会导致这个循环永远无法结束。 

要注意语句序列的对齐,while语句只执行其后的一条或一组同一层次的语句。

i = 0
while i <10:print(i)i &#43;&#61; 1
print("结束循环")


使用while循环遍历列表和元组&#xff1a;由于列表和元组都是有索引的&#xff0c;因此程序可通过while循环、列表或元组的索引来比那里列表和元素中的所有元素。

a &#61; ("燕双嘤", "杜马", "陈恭鹏")
i &#61; 0
while i

循环使用else&#xff1a;Python的循环可以定义else代码块&#xff0c;当循环条件为False时&#xff0c;程序会执行else代码块。

i &#61; 0
while i <5:print(i)i &#43;&#61; 1
else:print("大于或等于5")


3.2&#xff0c;for循环


for-in循环专门用于遍历范围、列表、元素和字典等可迭代对象包含的元素。for-in循环的语法格式如下&#xff1a;

for 变量 in 字符串|范围|集合等:statement

for-in循环中的变量的值受for-in循环控制&#xff0c;该变量将会在每次循环开始时自动被赋值&#xff0c;因此程序不应该在循环中对该变量赋值。

for-in循环可用于遍历任何可迭代的对象。所谓迭代对象&#xff0c;就是指该对象中包含一个_iter_方法&#xff0c;且该方法的返回值对象具有next()方法。

for i in range(1,10,1):print(i)

PS&#xff1a;for-in循环的循环计数器赋值在语法上是允许的&#xff0c;但是没有什么意义。 


使用for-in循环遍历列表和元组&#xff1a;在使用for-in循环遍历列表和元组时&#xff0c;列表或元组有几个元素&#xff0c;for-in循环的循环体就执行几次&#xff0c;针对每个元素执行一次&#xff0c;循环计数器会一次被赋值为元素的值。

a &#61; ("燕双嘤","杜马","步鹰")
for i in a:print(i)
for i in range(0,len(a)):print(a[i])


使用for-in循环遍历字典其实也是通过遍历普通列表来实现的。通过以下方法&#xff1a;

  • items()&#xff1a;返回字典中所有key-value的列表。
  • keys()&#xff1a;返回字典中所有key的列表。
  • values()&#xff1a;返回字典中所有value的列表。

a &#61; {"name": "燕双嘤", "sex": "男", "age": 22}
for key,value in a.items():print(key,value)print(key,a[key])


4&#xff0c;控制结构


4.1&#xff0c;使用break结束循环


某些时候&#xff0c;需要在某种添加出现时强制中止循环&#xff0c;而不是等到循环条件为False时才退出循环。此时可以使用break来完成这个功能。break用于完全结束一个循环&#xff0c;跳出循环体。不管是哪种循环&#xff0c;一旦在循环体中遇到break&#xff0c;系统就将完全结束该循环&#xff0c;开始执行循环之后的代码。双层循环之跳出内层循环体。

for i in range(0,100):print(i)if i &#61;&#61; 10:break


4.2&#xff0c;使用continue忽略本次循环的剩下语句


continue的功能和break有点类似&#xff0c;区别是continue知识忽略当次循环的剩下语句&#xff0c;接着下一次循环&#xff0c;并不会中止循环&#xff1b;而break则是完全中止循环本身。

for i in range(0,100):print(i)if i &#61;&#61; 10:continueprint(123)


4.3&#xff0c;使用return结束方法


return用于从包围它的最直接方法、函数或匿名函数返回。当函数或方法执行到一条return语句时&#xff0c;这个函数或方法将被结束。Python程序中大部分循环都被放在函数或方法中执行&#xff0c;一旦在循环体内执行到一条return语句时&#xff0c;retrun语句就会结束该函数或方法&#xff0c;循环自然也随之结束。

def test():for i in range(0, 100):print(i)if i &#61;&#61; 10:returnprint(123)
if __name__ &#61;&#61; &#39;__main__&#39;:test()


5&#xff0c;函数的定义


函数和方法的区别&#xff1a;看它的调用者是谁&#xff0c;如果是类&#xff0c;那么就需要传入一个参数self的值&#xff0c;这时它就是一个函数。如果调用者是对象&#xff0c;那么就不需要给self传入参数值&#xff0c;这时它就是一个方法。


5.1&#xff0c;函数的概念


函数是组织好的、可重复使用的、用来实现单一或相关联动功能的代码段。函数将一个大而复杂的原始人物分解为多个较简单的子任务&#xff0c;再为每个子任务设计算法&#xff0c;将描述其算法的这一组语句封装为一个独立代码块&#xff0c;为每个独立代码块定义一个名字以及能与其他独立代码块通信的接口&#xff0c;在整体上简化程序结构&#xff0c;降低程序开发和修改的复杂度&#xff0c;提高程序的可读性、可维护性和可复用性。

函数的目的是把一些复杂的操作进行封装&#xff0c;来简化程序的结构&#xff0c;使其容易阅读。函数在调用前&#xff0c;必须先定义。也可以在一个函数内部定义函数&#xff0c;内部函数只有在外部函数调用时才能够被执行。程序调用函数时&#xff0c;转到函数内部执行内部的语句&#xff0c;函数执行完毕后&#xff0c;返回到它离开程序的地方&#xff0c;执行程序的下一条语句。

Python中的函数包括&#xff1a;内建函数、标准库函数、第三方库函数、用户自定义函数。


5.2&#xff0c;函数的定义


定义函数的规则&#xff1a;

  • 函数代码块以def关键词开头&#xff0c;后接函数标识符名称和圆括号()。
  • 任何传入参数和自变量必须放在圆括号中间&#xff0c;圆括号中间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串&#xff0c;用于存放函数说明。
  • 函数内容以冒号起始&#xff0c;并且缩进。
  • return用于结束函数&#xff0c;选择性地返回一个值给调用者。不带return相当于返回None。

定义函数的语法格式&#xff1a;

def 函数名(形参列表)://由零条到多条可执行语句组成的函数[return [返回值]]

Python声明函数必须使用def关键字&#xff0c;对函数语法格式的详细说明&#xff1a;

  • 函数名&#xff1a;从语法角度来看&#xff0c;函数名只要是一个合法的标识即可&#xff1b;从程序的可读性角度来看&#xff0c;函数名应该由一个或多个有意义的单词组成&#xff0c;每个单词的字母全部小写&#xff0c;单词与单词之间使用下划线分隔。
  • 形参列表&#xff1a;用于定义该函数可以接收的参数。形参列表由多个形参名组成&#xff0c;多个形参名之间以英文逗号&#xff08;,&#xff09;隔开。

def demo(x):print("燕双嘤"&#43;str(x))return "哈哈哈"
print(demo("NB"))


5.3&#xff0c;函数的定义&#xff08;lambda函数、匿名函数&#xff09; 


Python中有两种定义函数的方式&#xff0c;一种是用关键字def进行定义。使用这种方式定义函数时需要指定函数的名称&#xff0c;这类函数被称为普通函数&#xff1b;另外一种函数是用关键字lambda进行定义&#xff0c;不需要指定函数的名字&#xff0c;这类函数被称为lambda函数。

lambda函数又被称为匿名函数&#xff0c;它是一种单行的小函数&#xff0c;语法简单&#xff0c;简化代码&#xff0c;不会产生命名冲突&#xff0c;也不会占用命名空间。lambda函数是一个可以接受任意多个函数并且返回单个表达式值的函数。lambda函数返回的表达式不能超过一个。因此不要视图尝试使用lambda函数来实现复杂的业务逻辑功能&#xff0c;因为这会使得代码难以理解。如果有这种需求&#xff0c;应该使用普通函数来实现。

普通函数与lambda的相同点&#xff1a;

  • 都可以定义固定的方法和程序处理流程。
  • 都可以包含参数。

普通函数与lambda的不同点&#xff1a;

  • lambda函数代码更简洁&#xff0c;但是def定义的普通函数更为直观、易理解。
  • def定义的是普通函数&#xff0c;而lambda定义的是表达式。
  • lambad函数不能包含分支或者循环&#xff0c;不能包含return语句。
  • 关键字lambda用来创建匿名函数&#xff0c;而关键字def用来创建有名称的普通函数。

lambda函数的语法&#xff1a;

lambda 参数:表达式

sum &#61; lambda x, y&#61;0, z&#61;0: x &#43; y &#43; z
print(sum(1, 2))
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
3

上面也可以直接使用lambda函数

print((lambda x, y&#61;0, z&#61;0: x &#43; y &#43; z)(1,2,3))


5.4&#xff0c;多个返回值


如果程序需要有多个返回值&#xff0c;则既可将多个值包装成列表之后返回&#xff0c;也可直接返回多个值。如果Python函数值直接返回了多个值&#xff0c;Python会自动将多个返回值封装成元组。

def demo():print("燕双嘤")return "哈哈哈","嘤嘤嘤"
print(demo())
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤
(&#39;哈哈哈&#39;, &#39;嘤嘤嘤&#39;)


5.5&#xff0c;下划线的意义


单下划线&#xff08;_&#xff09;&#xff1a;在交互解释器中&#xff0c;表示上一条语句执行输出结果。另外&#xff0c;单下划线还可以作为特殊的临时变量&#xff0c;表示在后面将不会再用到这个变量&#xff08;实际可以使用&#xff09;。

for _ in range(5):print("Python")

名称前的单下划线&#xff08;_name&#xff09;&#xff1a;指定属性或方法只能在内部使用&#xff0c;是API中非公开的部分&#xff0c;不能被"from import *"和"from import *"导入程序&#xff0c;除非在“_all_”列表中包含了以单下划线开头的属性、方法或类。

class _a:_b &#61; 1def _c(self):print(self._b)

名称前的双下划线&#xff08;__name&#xff09;&#xff1a;以双下划线开头的属性或方法可以避免父类的属性和方法被子类轻易覆盖&#xff0c;一般不建议这样定义属性和方法。如果调用以双下划线开头的方法和属性&#xff0c;就必须以“_类名_方法&#xff08;属性&#xff09;”的形式就可以实现方法或者属性的访问了。类名前面是单下划线&#xff0c;类名后是双下划线&#xff0c;然后再加上方法或属性。但是不建议调用&#xff0c;因为这是Python内部进行调用的形式。Python这么做的目的为了避免父类的方法被子类轻易覆盖。

名称前后的双下划线&#xff08;name__&#xff09;&#xff1a;这类方法是Python内部定义的方法&#xff0c;可以重写这些方法&#xff0c;这样Python就可以调用这个重写的方法。可以经常看到类似“__init__”的方法&#xff0c;这表示在Python内部调用的方法&#xff0c;一般不建议在程序中调用。例如&#xff0c;当调用len()方法时&#xff0c;实际上调用了Python中内部的__len__方法&#xff0c;虽然不建议调用这种这种以双划线开头以及结尾的方法&#xff0c;但是可以对这些方法进行重写。


6&#xff0c;函数的参数


6.1&#xff0c;关键字参数


按照形参位置传入参数被称为位置参数&#xff1a;

  • 如果使用位置参数的方式传入参数值&#xff0c;则必须严格按照定义函数时指定的顺序来传入参数值。
  • 如果根据参数名来传入参数值&#xff0c;则无须遵守定义形参的顺序&#xff0c;这种方式被称为关键字参数。

def demo(str1, str2):print(str1, str2)return "哈哈哈"print(demo("燕双嘤", "NB"))
print(demo(str2&#61;"燕双嘤", str1&#61;"NB"))
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤 NB
哈哈哈
NB 燕双嘤
哈哈哈


6.2&#xff0c;默认参数


在某些情况下&#xff0c;程序需要在定义函数时为一个或多个形参指定默认值——这样在调用函数式就可以省略为该形参传入参数值&#xff0c;而是直接使用该形参的默认值。

def area(r,pi &#61; 3.14):return (r*r*pi)print(area(5))

PS&#xff1a;多个参数时&#xff0c;有默认值的参数必须放在无默认值参数的后面。


6.3&#xff0c;可变参数


*和**主要用于函数的定义。当函数的参数不确定时&#xff0c;可以使用*a和**b来将不定数量的参数传递给一个函数。

  • *a&#xff1a;用来发送一个非键值对的可变数量的参数列表给一个函数。*a会接受任意多个参数并把这些参数作为元组传递给函数。*a没有key值&#xff0c;以元组形式传递。
  • **b&#xff1a;存储可变的关键字参数&#xff0c;允许使用没有事先定义的参数名&#xff0c;将接收到任意多个关键字参数作为字典传递给函数。**b有key值&#xff0c;以字典形式传递。

需要注意的是&#xff0c;函数的参数的顺序&#xff1a;*a必须在**b前面&#xff0c;调用函数传递参数也必须依照此顺序。


Python允许在形参前面添加一个星号&#xff08;*&#xff09;&#xff0c;这样就意味着该参数可接收多个参数值&#xff0c;多个参数值被当成元组传入。

def demo(a,*b):print(a)for i in b:print(i,end&#61;" ")print()print(b)
demo("燕双嘤",1,2,3,4,5)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤
1 2 3 4 5
(1, 2, 3, 4, 5)

PS&#xff1a;Python允许可变参数出现在列表的任何位置&#xff0c;但Python要求函数最多只能带一个支持“普通”参数收集的形参。

def demo(*b,a):print(a)for i in b:print(i)
demo("燕双嘤",1,2,3,4,a&#61;5)

demo()函数的第一个参数就是个数可变的形参&#xff0c;由于该参数可接收个数不等的参数值&#xff0c;因此如果需要给后面的参数传入参数值&#xff0c;则必须使用关键字参数&#xff1b;否则&#xff0c;程序会把所传入的多个值都当成是传给b参数的。


Python还可以收集关键字参数&#xff0c;此时Python会将这种关键字参数收集字典。为了让Python能收集关键字参数&#xff0c;需要在参数前面添加两个星号。在这种情况下&#xff0c;一个函数可同时包含一个支持“普通”参数收集的参数和一个支持关键字参数收集的参数。

def test(x, y, z&#61;3, *names, **part):print(x, y, z)print(names)print(part)
test(1, 2, 3, "燕双嘤", "杜马", 党派1&#61;"共产党", 党派2&#61;"国民党")
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
1 2 3
(&#39;燕双嘤&#39;, &#39;杜马&#39;)
{&#39;党派1&#39;: &#39;共产党&#39;, &#39;党派2&#39;: &#39;国民党&#39;}

如果想让z参数的默认值发挥作用&#xff0c;则需要只传入两个位置参数。

part &#61; {"党派1": "共产党", "党派2": "国民党"}
test(1, 2, **part)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
1 2 3
()
{&#39;党派1&#39;: &#39;共产党&#39;, &#39;党派2&#39;: &#39;国民党&#39;}


6.4&#xff0c;逆向参数


所谓逆向参数收集&#xff0c;指的是在程序已有列表、元组、字典等对象的前提下&#xff0c;把它们的元素“拆开”后传给函数的参数。

def test(num1,num2, *nums):print(num1)print(num2)print(nums)
list &#61; [1, 2, 3]
test(*list)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
1
2
(3,)


6.5&#xff0c;传参机制


Python中函数的参数传递机制都是“值传递”&#xff0c;就是将实际参数值的副本传入函数&#xff0c;而参数本身不会受到任何影响。引用传递指的是&#xff0c;在调用函数时&#xff0c;将实际参数的地址传递给函数&#xff0c;这样在函数中对参数的修改将会直接影响到实际参数。

  • 对于不可变类型&#xff08;数值型、字符串、元组&#xff09;因为变量不能被修改&#xff0c;所以运算不会影响到变量自身&#xff0c;可以认为函数的参数传递是值传递。
  • 对于可变类型&#xff08;列表、字典&#xff09;来说&#xff0c;函数内的运算可能会更改传入的参数变量&#xff0c;可以认为函数的参数传递是引用传递。

def swap(a, b):a, b &#61; b, aprint("在swap函数里&#xff1a;", a, b)
a &#61; 6
b &#61; 9
swap(a, b)
print("交换结束后&#xff1a;", a, b)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
在swap函数里&#xff1a; 9 6
交换结束后&#xff1a; 6 9

def swap(ab):ab[&#39;a&#39;], ab[&#39;b&#39;] &#61; ab[&#39;b&#39;], ab[&#39;a&#39;]print(ab["a"], ab["b"])
ab &#61; {"a":6,"b":9}
swap(ab)
print(ab["a"], ab["b"])
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
9 6
9 6


7&#xff0c;变量作用域


在程序定义一个变量时&#xff0c;这个变量是有作用范围的&#xff0c;变量的作用范围被称为它的作用域。根据定义变量的位置&#xff0c;变量分为两种&#xff1a;

  • 局部变量&#xff1a;在函数中定义的变量&#xff0c;包括参数&#xff0c;都被称为局部变量。每个函数在执行时&#xff0c;系统都会为该函数分配一块“临时内存空间”&#xff0c;所有的局部变量都被保存在这块临时内存空间内。当函数执行完成后&#xff0c;这块内存空间就被释放了&#xff0c;这些局部变量也就失效了&#xff0c;因此离开函数之后就不能再访问局部变量了。
  • 全局变量&#xff1a;在函数外面、全局范围内定义的变量&#xff0c;都被称为全局变量。全局变量意味着它们可以在所有函数内被访问。

此外&#xff0c;Python提供了如下三个工具函数来获取指定范围内的“变量字典”&#xff1a;

  • globals()&#xff1a;该函数返回全局范围内所有变量组成的“变量字典”。
  • locals()&#xff1a;该函数返回当前局部返回内所有变量组成的“变量字典”。
  • vars(object)&#xff1a;获取在指定对象范围内所有变量组成的“变量字典”。如果不传入object参数&#xff0c;vars()和locals()的作用完全相同。

globals()locals()看似完全不同&#xff0c;但它们实际上也是有联系的&#xff0c;关于这两个函数的区别如下&#xff1a;

  • locals()总是获取当前局部范围内所有变量组成的“变量字典”&#xff0c;因此&#xff0c;如果在全局范围内调用locals()函数&#xff0c;同样会获取全局范围内所有变量组成的“变量字典”&#xff1b;而globals()无论在哪里执行&#xff0c;总是获取全局范围内所有变量组成的“变量字典”。
  • 一般来说&#xff0c;使用locals()和globals()获取的“变量字典”只应该被访问&#xff0c;不应该被修改。但实际上&#xff0c;不管是使用globals()还是使用locals()获取的全局范围内的“变量字典”&#xff0c;都可以被修改&#xff0c;而这种修改回真正改变全局变量本身&#xff1b;但通过locals()获取的局部范围内的“变量字典”&#xff0c;即使对它修改也不会影响局部变量。

def test():age &#61; 20print(age)print(locals())locals()[&#39;age&#39;] &#61; 12print(age)globals()[&#39;x&#39;] &#61; 19test()
x &#61; 5
y &#61; 20
print(globals())
print(locals())
print(x)
print(globals()[&#39;x&#39;])
globals()[&#39;x&#39;] &#61; 39
print(x)
locals()[&#39;x&#39;] &#61; 99
print(x)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
20
{&#39;age&#39;: 20}
20
{&#39;__name__&#39;: &#39;__main__&#39;, &#39;__doc__&#39;: None, &#39;__package__&#39;: None, &#39;__loader__&#39;: <_frozen_importlib_external.SourceFileLoader object at 0x0000017A902DC1D0>, &#39;__spec__&#39;: None, &#39;__annotations__&#39;: {}, &#39;__builtins__&#39;: , &#39;__file__&#39;: &#39;E:/Pycharm/WorkSpace/Study/main.py&#39;, &#39;__cached__&#39;: None, &#39;test&#39;: , &#39;x&#39;: 5, &#39;y&#39;: 20}
{&#39;__name__&#39;: &#39;__main__&#39;, &#39;__doc__&#39;: None, &#39;__package__&#39;: None, &#39;__loader__&#39;: <_frozen_importlib_external.SourceFileLoader object at 0x0000017A902DC1D0>, &#39;__spec__&#39;: None, &#39;__annotations__&#39;: {}, &#39;__builtins__&#39;: , &#39;__file__&#39;: &#39;E:/Pycharm/WorkSpace/Study/main.py&#39;, &#39;__cached__&#39;: None, &#39;test&#39;: , &#39;x&#39;: 5, &#39;y&#39;: 20}
5
5
39
99


在函数中声明全局变量

name &#61; "燕双嘤"def test():global nameprint(name)name &#61; "杜马"test()
print(name)
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤
杜马


8&#xff0c;高级函数


8.1&#xff0c;局部函数


前面所有的函数都是在全局范围内的函数&#xff0c;被称为全局函数。Python还支持在函数体内定义函数&#xff0c;这种被放在函数体内定义的函数被称为局部函数。

在默认情况下&#xff0c;局部函数对外部是隐藏的&#xff0c;局部函数只能在其封闭函数内有效&#xff0c;其封闭区函数可以返回局部函数&#xff0c;以便程序在其他作用域中使用局部函数。

def global_def(type, n):def square(n):return n * ndef cube(n):return n * n * nif type &#61;&#61; "square":return square(n)elif type &#61;&#61; "cube":return cube(n)print(global_def("square", 3))
print(global_def("cube", 3))
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
9
27

局部函数内的变量也会覆盖其所在函数内的局部变量&#xff1a;

这就是因为局部变量覆盖局部变量导致的&#xff0c;update内定义的name局部变量覆盖了test内的name局部变量&#xff0c;因此导致程序报错。为了解决这个问题&#xff0c;Python提供了nonlocal关键字&#xff0c;通过nonlocal语句即可声明访问赋值语句只是访问该函数所在函数内的局部变量。

def test():name &#61; "燕双嘤"def update():nonlocal nameprint(name)name &#61; "杜马"update()print(name)
test()
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤
杜马


8.2&#xff0c;函数作为变量


Python的函数也是一种值&#xff1a;所有函数都是function对象&#xff0c;这意味着可以把函数本身赋值给变量&#xff0c;就像把整数、浮点数、列表、元组赋值给变量一样。将函数赋值给变量可以让程序更加灵活。

def test():name &#61; "燕双嘤"print(name)a&#61;test
a()
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
燕双嘤


8.3&#xff0c;函数作为参数


有时候需要定义一个函数&#xff0c;该函数的大部分计算逻辑能确定&#xff0c;但某些处理逻辑暂时无法确定——这意味着某些程序代码需要动态改变&#xff0c;如果希望调用函数时能动态传入这些代码&#xff0c;就需要在函数中定义函数形参&#xff0c;这样即可在调用该函数时传入不同的函数作为参数&#xff0c;从而动态改变这段代码。

def map(data,fn):result &#61; []for e in data:result.append(fn(e))return result
def square(n):return n*n
def cube(n):return n*n*n
data &#61; [3,4,5,6,7]
print(map(data,square))
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
[9, 16, 25, 36, 49]


8.4&#xff0c;函数作为返回值


Python中支持使用函数作为其他函数的返回值。

def global_def(type):def square(n):return n * ndef cube(n):return n * n * nif type &#61;&#61; "square":return squareelif type &#61;&#61; "cube":return cube
a &#61; global_def("cube")
print(a(5))
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
125


推荐阅读
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
author-avatar
手机用户2502858383_827
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有