看深度学习的代码时,看到类和方法以及一些装饰符,才发现自己基础这么薄弱,有必要多学习几次基础知识
函数其实就是有一个特定功能的代码段。
比如print()
对于已经包装好的函数,我们只需要通过函数名(参数)来调用即可
对于函数调用时,我们需要注意:
(1)函数名是什么。
(2) 函数调用时我们是否需要传入参数。
(3)函数是否由返回值以及函数的返回值是什么。
例如:
input函数我们可以提供参数,也可以不提供参数,input()函数有返回值。我们可以通过一个变量来接受,也可以让其直接参与运算。
比如 len(s) len()函数是必须要有参数的。
print()可以有多个参数,参数要用逗号分隔开。默认print不同参数用一个空格分隔开,且自动换行,我们可以根据end=“”,sep=""来进行调整。
其实函数调用时我们传入的参数就是我们给函数的数据,函数的功能已经有了,只是我们传入的值不同罢了。
def 函数名(参数):
函数体
函数在定义时 要注意函数的命名规则,参数个数。
对于参数,我们可以不用指定其类型,但是如果想要提示,也可以指定类型。
比如
def say_hi(a:str):
"""
huaxian
"""
print(a)
如果我们指定了函数类型,我们在IDE中就可以自动得到字符串的一些函数。
但是我们只是指定了其类型,并不是限定只能是字符串。a也可以是其他类型。
函数可以有返回值,函数的返回值就是函数执行之后的结果,函数也可以有多个返回值,写在return后,用逗号分隔开。return可以提前结束函数。
当函数有多个返回值时,我们可以用一个变量来接收,此时是一个元组类型,也可以用对应数量的多个变量来接收。
def say_hi():
"""
huaxian
"""
return "a","b","c"
d=say_hi()
print(d)
这里编写了一个日历代码
def get_week_with_date(y,m,d):
'''
根据日期获得星期几
'''
if m==1 or m==2:
y-=1
m+=12
return (d+2*m+3*(m+1)//5+y+y//4-y//100+y//400+1)%7
def is_leap_year(y):
'''
判断是否是闰年
'''
if (y%400==0) or (y%4==0 and y%100!=0):
return True
return False
def get_days_with_month(m,y):
'''
获得该月有几天
'''
if m in[1,3,5,7,8,10,12]:
return 31
elif m in[4,6,11]:
return 30
else:
return 27 if is_leap_year(y) else 28
# year=int(input("请输入年份:"))
# month=int(input("请输入月份:"))
year=2023
month=4
day=get_days_with_month(month,year)
print("一 二 三 四 五 六 日")
print("-"*20)
for i in range(1,day+1):
w=get_week_with_date(year,month,i)
if i==1:
print(f"{' '*(w-1)*3}",end="")
else:
if w==1:
print("")
print(f"{i:2d}",end=" ")
有局部变量 local
和全局变量 global
局部变量只能在函数内部使用以及修改。
而全局变量可以在函数内外使用,可以在函数外修改,如果要在函数内修改全局变量的值必须加上 global
i=0
def f():
i=22
print(i)
f()
print(i)
22
0
i=0
def f():
global i
i=22
print(i)
f()
print(i)
22
22
在定义函数时,我们可以给参数加上默认值,但是注意,默认值参数是从后往前依次设置的,若后边的值没有默认值,则前面的参数也不能设置默认值。
def f(a,b=0,c=0):
print(a,b,c)
f(1)
b可以设置默认值的前提是 c已经设置了默认值。
通常,如果我们不指定,则就是顺序参数。
但是我们也可以使用关键词参数,需要注意的是:一旦一个参数使用了关键词参数,则后边的参数都要使用关键词参数。
错误示例:
如果b使用了关键词参数,则c也要使用关键词参数。
def f(a,b,c):
print(a,b,c)
f(12,b=12,12)
使用关键词参数可以打乱赋值顺序。关键词参数也可以和默认值参数联合:
def f(a,b=2,c=0):
print(a,b,c)
f(12,c=1)
12 2 1
在定义函数时,我们可以在形参前加上一个*,即可变为可变参数。
可变参数可以和普通参数结合使用。
可变参数前的普通参数不能使用关键词赋值,因为只要使用了关键词参数,其后边的所有参数都必须使用关键词参数,而可变参数是不能使用关键词参数的。可变参数之后的普通参数必须使用关键词参数。
def f(a,b,*arg,c,d):
print(arg)
f(1,2,3,4,c=1,d=1)
(3,4)
可变关键词参数必须出现在参数的最后一个位置。
可变关键词参数可以与可变参数和普通参数一起使用
可变参数前的普通参数必须使用顺序赋值。
def f(a,b,*arg,d,**kwarg):
print(arg)
print(kwarg)
for k,v in kwarg.items():
print(k,v)
f(1,3,4,c=1,e=1,d=2)
(4,)
{‘c’: 1, ‘e’: 1}
c 1
e 1
所有可迭代对象都有解包操作。
比如字符串,元组,列表,字典。
函数调用时的*与 **和函数定义时的不同。
函数调用时的*和 **表示为可迭代对象解包。
* *表示为字典解包
* 表示为其它的可迭代对象解包
函数也可以作为一个参数来传递,至于有什么用处,可以见下面这个例子。
一个函数只实现一个具体的功能,但如果我们想在其去实现其它功能,我们就可以将函数作为一个参数类型。
import datetime
#这里就是以函数为参数,一个函数往往只实现一个功能,这样子做可以让我们减少参数修改
#如果开始时要做的功能不一样,我们只用传入该函数即可,而不用去修改计时器函数
def timer(t,start,end):
'''
实现一个计时器功能,在计时开始时我们去实现start函数功能
计时结束后,我们去实现end函数功能
:param t: 计时器时间
:param start: 开始要执行的函数
:param end: 结束要执行的函数
:return:
'''
time=datetime.datetime.now()
if start:
start()
while True:
now=datetime.datetime.now()
if (now-time).seconds>=t:
break
if end:
end()
def start():
print("稍等两秒钟")
def end():
input("可以了,请输入密码:")
timer(2,start,end)
在函数内部定义一个函数,且返回,叫做闭包。
def counting(count):
def fn():
nonlocal count
count-=1
if count<0:
return
return count
return fn
a=counting(5)
b=counting(3)
print(a())
print(a())
print(a())
4,3,2
调用counting函数时,首先把count传入,接着 def fn() ,return fn;
把count的值以及fn函数本身打包,返回给了a,是一个环境变量。
b也是一个环境,a和b是互不影响的,所以可以同时设置多个计时器。
def f(fn):
def f2(count):
def f1():
for i in range(1,count):
return fn(i)
return f1
return f2
@f
def foo(x):
return 2*x
a=foo(5)()
print(a)
2
比如这个
首先 foo(5) 即 f(foo) 返回一个f2 之后 f2(5) 返回一个f1
f1() 就调用了f1()函数
对于有些简单函数,我们可以不必单独定义一个函数。
比如
def fn(x):
return x2
此时我们可以使用匿名函数。
lambda x:x2
这和上边的函数功能一致。
匿名函数 都要有lambda标识,不必有函数名,且冒号后边的就是返回值,所以不必写return。匿名函数的参数和普通函数的参数一样,但是匿名函数的参数不能使用指定类型的操作,会和后边的冒号冲突。
在函数体内调用自身。
def fn(a):
if a<=1:
return 1
else:
return fn(a-1)*a
fn(3)