python笔记-06(函数与参数)

1、自定义函数

使用callable函数可以查看某个对象是否可以调用

x = 1
y = math.sqrt
print(callable(x))
print(callable(y))

运行结果
False
True

①、文档字符串

def fib(num):
    # 文档字符串
    '计算斐波那契数组'
    fibs = [0, 1]
    for i in range(num - 2):
        fibs.append(fibs[-1] + fibs[-2])
    return fibs


print(fib(10))
print(fib.__doc__)

运行结果
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
计算斐波那契数组

②、形参与实参:如果打印method1的返回值为None

def method1(name):
    print("name开始的地址:" + str(id(name)))
    name = "tom"
    print("name修改后的地址:" + str(id(name)))
    print("name:" + name)


n = "tony"
# n与name开始指向同一个对象
print("n开始的地址:" + str(id(n)))
method1(n)
print("调用方法后n的地址:" + str(id(n)))

运行结果
n开始的地址:2549500688816
name开始的地址:2549500688816
name修改后的地址:2549500688752
name:tom
调用方法后n的地址:2549500688816

可以看到n和name变量的变化,但是如果形参是列表这种可以修改的类型,对列表的元素进行修改会导致实参的值发生变化,如果想要避免这种情况可以传递实参的副本

def method2(list1):
    list1[0] = "hello"
    print("修改后的list1:", end="")
    print(list1)


# 如果是传入的列表,然后对列表元素进行了修改会影响实参的值
l = ["java", "c", "c++", "python"]
print("修改前的l:", end="")
print(l)
method2(l)
print("修改后的l:", end="")
print(l)
# 如果传过去的是原列表的拷贝,则不会对原列表产生影响
l = ["java", "c", "c++", "python"]
print("修改前的l:", end="")
print(l)
method2(l[:])
print("修改后的l:", end="")
print(l)

运行结果
修改前的l:['java', 'c', 'c++', 'python']
修改后的list1:['hello', 'c', 'c++', 'python']
修改后的l:['hello', 'c', 'c++', 'python']
修改前的l:['java', 'c', 'c++', 'python']
修改后的list1:['hello', 'c', 'c++', 'python']
修改后的l:['java', 'c', 'c++', 'python']

 ③、关键字参数与默认参数:调用函数时可以指定参数名称,此时可以不用在乎参数传递的顺序。同时形参列表中还可以指定默认值

# 可指定默认值
def method3(name="tony", sex="female"):
    print("name:" + name, "sex:" + sex)


print("关键字参数")
method3(sex="male", name="tom")
method3(sex="male")

运行结果
关键字参数
name:tom sex:male
name:tony sex:male

在关键字参数中有一个需要重视的地方:如下代码,method1中使用了空列表作为默认参数,当调用该函数传入参数时一切正常,但是当单独调用时发现每调用一次,l的个数就多一个而不是只有一个end。这是因为在函数定义时,默认参数 l 就会被计算出来,指向 [ ] 这个地址,所以每次调用时都会改变这个地址中的内容。

# -*- coding:utf-8 -*-
# 默认参数需要注意的地方
def method1(l=[]):
	l.append("end")
	print(l)


def main():
	l = [1, 2, 3]
	method1(l)
	method1(l)
	method1()
	method1()


if __name__ == "__main__":
	main()

输出结果:

对于该代码,可以使用l=None的方式进行改进。

# -*- coding:utf-8 -*-
# 默认参数需要注意的地方
def method1(l=None):
	if l == None:
		l = []
	l.append("end")
	print(l)


def main():
	l = [1, 2, 3]
	method1(l)
	method1(l)
	method1()
	method1()


if __name__ == "__main__":
	main()

④、收集参数,*参数(可变参数)被收集到元组中,**参数(关键字参数)被收集到字典中

# 收集参数 *将参数收集到一个元组中,但是不会收集关键字参数,**收集关键字参数成一个字典
def method4(name="tom", age=23, *params1, **params2):
    print("name:", name)
    print("age:", age)
    print(params1)
    print(params2)


method4("tony", 12, "male", "162cm", "SiChuan", salary="10000", phone="110")


运行结果
name: tony
age: 12
('male', '162cm', 'SiChuan')
{'salary': '10000', 'phone': '110'}




在传入params1参数时,还可以定义一个list或tuple,然后使用*list名称或*tuple名称将其传入到函数中

⑤、分配参数

# 分配参数
def method5(x, y, z=5, w=6):
    print(x + y + z + w)


params1 = (2, 3)
params2 = {"z": 2, "w": 3}
method5(*params1, **params2)

运行结果
10

⑥、作用域

 在函数体内的变量,没有指明都为局部变量。当全局变量和局部变量名称相同时,在函数体内用到的都是局部变量,对该局部变量修改不会影响全局变量的值。如下

# 测试作用域
x = 0


def scopetest():
    x = 2
    print(x)


scopetest()
print(x)

运行结果
2
0

使用globals和global可以在函数体内引用全局变量,使用global的方式也叫重新关联全局变量。

x = 0
def scopetest1():
    globals()['x'] = 1
    print(x)


scopetest1()
print(x)


def scopetest2():
    global x
    x += 1
    print(x)


scopetest2()
print(x)

运行结果
1
1
2
2

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值