定义的时候用的是形式参数 不需要声明类型 也不需要指定函数返回值类型
实际参数 必须与形式参数列表内的一一对应
def print_max(a,b):
'''
实现两个数的比较并返回较大的值
:param a:一个参数
:param b:一个参数
:return:返回较大的参数
'''
if a<b:
print(a,"较大值")
return a
else:
print(b,"较大值")
return b
print_max(10,30)
print_max(10,5)
# 10 较大值
# 5 较大值
可以通过这个获得文档字符串的内容 就是公式对应的注释的内容
# 文档字符串(函数的注释)
# 好的代码就是易读的代码 短和易懂
def print_star(n):
'''
根据传入的n,打印多个星号
:param n: 传入的数字
:return: n个星号拼接的字符串
'''
s = "*"*n
print(s)
return s
help(print_star) # 这里不需要添加括号 括号是用来调用的时候运用的
print(print_star.__doc__)
# 这两个方法可以获得这个公式的文档字符串 就是可以通过这两个方法来获得这个公式的注释
返回值
# 返回值的作用 :结束函数运行 返回指定值给调用者 # return返回值要点: # 函数体中包含return语句则结束函数执行并返回值 # 函数体中不包含return语句则返回None值 # 要返回多个值 把多个值放到一个序列里面
# 定义一个无返回值的星号函数
def print_star(n):
print("*"*n)
# return n
c = print_star(5)
# print(c)
# *****
# 定义一个返回两个数平均值的函数
def my_avg(a,b):
return (a+b)/2
a = my_avg(20,30)
print(a)
# 25.0
# 返回一个列表
def printShape(n):
s1 = "#"*n
s2 = "$"*n
return[s1,s2]
s = printShape(5)
print(s)
print(type(s))
print(type(printShape(5)))
print(type(printShape))
# <class 'list'>
# <class 'list'>
# <class 'function'>
# ['#####', '$$$$$']
函数也是对象 内存分析(与后面的面向对象有一些关系)
python中一切都是对象
实际上执行def定义函数之后,系统就创建了相应的函数对象
# 函数也是对象 内存底层分析 (引申面向对象)
def print_star(n):
print("*"*n)
print(print_star)
print(id(print_star))
print(type(print_star))
# <function print_star at 0x00000216C11D4AE0>
# 2296752458464 # 可以指示出这个函数是一个对象
# <class 'function'>
执行def定义函数之后 就相当于创建了一个堆内存 里面有id有type有函数对象的属性方法等内容 然后还有一个栈内存里面有一个函数名本质上就是一个变量 变量引用了这个id(持有了这个对象的地址) 也就调用了这个函数
函数运用的时候再栈内存里面 对象建好的时候在堆内存里面
python中()意味着调用函数 在没有()的情况下意味着把函数当做普通对象
def print_star(n):
print("*"*n)
c = print_star
# c和print_star 指向的是同一个对象
c(3)
# ***
zhengshu = int
# 相当于两个变量指向同一个对象
print(zhengshu('3333'))
# 3333
s = str
print(s(333))
# 333
# 一些额外的小细节
str = 'dddd' # 起一些变量的名字的时候尽量不要起跟内置函数一样的名字
print(str)
print(str(333)) # 就像这样str换了一个对象进行引用 就不能作为一个内置函数进行使用 就会进行报错了
函数也是对象
变量的作用域 全局变量 局部变量 栈帧内存分析详解
变量的作用域
全局变量
- 全局变量 指的是在函数之外(类之外)声明的变量 作用域为定义的模块 从定义为止开始直到结束位置
- 全局变量降低了函数的通用性和可读性 应尽量避免全局变量的使用
- 要在函数内改变全局变量的值 使用global声明一下
局部变量
- 在函数体中(包含形式参数)声明的变量
- 局部变量的引用比全局变量快 优先考虑使用
- 如果局部变量和全局变量同名,则在函数内隐藏全局变量,只使用同名的局部变量
a = 100
def f1():
print(a)
f1()
# 100
def f2():
b = 3
print(a+b)
f2()
# 103
def f3():
b = 3
a = 4
print(a+b)
f3()
print(a)
7 # 这里内部的a作为局部变量在函数内部进行使用
# 100 # 在外部进行打印的时候使用的还是全局变量
def f4():
b = 3
global a # 这里就可以改变全局变量
a = 4
print(a+b)
f4() # 当我们去调用一个方法的时候 栈内存就会启动一个栈帧stackframe
print(a)
# 7
# 4
a = 100
def f1(a,b,c):
print(a,b,c)
print(locals()) # 打印输出的局部变量
print("#"*20)
print(globals()) # 打印输出的全局变量
f1(2,3,4)
# 2 3 4
# {'a': 2, 'b': 3, 'c': 4}
# ####################
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000017CA8D5BBF0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\lenovo\\PycharmProjects\\pythonProject\\my02.py', '__cached__': None, 'a': 100, 'f1': <function f1 at 0x0000017CA8E95DA0>}
# '__doc__': None 这里就是文档字符串 这里没有所以就是None