Python 的函数是怎么传递参数的?

Python09

Python 的函数是怎么传递参数的?,第1张

首先你要明白,Python的函数传递方式是赋值,而赋值是通过建立变量与对象的关联实现的。

对于你的代码:

执行 d = 2时,你在__main__里创建了d,并让它指向2这个整型对象。

执行函数add(d)过程中:

d被传递给add()函数后,在函数内部,num也指向了__main__中的2

但执行num = num + 10之后,新建了对象12,并让num指向了这个新对象——12。

如果你明白函数中的局部变量与__main__中变量的区别,那么很显然,在__main__中,d仍在指着2这个对象,它没有改变。因此,你打印d时得到了2。

如果你想让输出为12,最简洁的办法是:

在函数add()里增加return num

调用函数时使用d = add(d)

代码如下:

def add(num):

num += 10

return num

d = 2

d = add(d)

print d

python中所有数据都是对象,所以传参也是传的对象的引用,这个引用在函数执行前和执行后是不会被改变的,如:

num = 1

def change(num):

print(id(num))

num = 2

print(id(num))

执行change(num)后num的值还是1

可以看到在执行前num的id值(可以理解为内存地址)是某一值

但在执行change后,num的id值改变了,也就是说内部的num指向了另外的对象,而外部的num却还是指向原来的对象,所以值没有变;

同理,如:

num_list = [1,2]

def change_list(num_list):

print(id(num_list))

num_list.append(3)

print(id(num_list))

可以看到执行change_list后num_list的id值没有改变,也就是说num_list是在原来的对象上添加了新的数据,外部的num_list也是指向这一对象,所以外部的num_list数据也添加了新的数据。

在一些测试平台对接时或者用例执行时,或多或少会用到Python脚本传参的问题。

test.py脚本

#!/usr/bin/python3

import sys

print ('参数个数为:', len(sys.argv), '个参数。')

print ('参数列表:', str(sys.argv))

print ('脚本名:', str(sys.argv[0]))

print ('第一个参数:', sys.argv[1])

执行python3 test.py arg1 arg2 arg3

参数个数为: 4 个参数。

参数列表: ['test.py', 'arg1', 'arg2', 'arg3']

脚本名: test.py

第一个参数: arg1

test.py脚本

#!/usr/bin/python3

import argparse

# 生成了一个命令行参数的对象

parser = argparse.ArgumentParser(description='Test for argparse')

parser.add_argument('--name', '-n', help='name属性,非必要参数')

parser.add_argument('--year', '-y', help='year 属性,非必要参数,但有默认值', default=2017)

parser.add_argument('--body', '-b', help='body属性,必要参数', required=True)

args = parser.parse_args()

print (args.year,  args.name, args.body)

查看帮助python3 test.py --help

usage: test.py [-h] [--name NAME] [--year YEAR] --body BODY

Test for argparse

optional arguments:

  -h, --help  show this help message and exit

  --name或-n NAME  name属性,非必要参数

  --year或-y YEAR  year属性,非必要参数,但有默认值

  --body或-b BODY  body 属性,必要参数

执行python3 test.py --year 2021 -n robot  --body "are you ok?"

2021 robot are you ok?

以方法2中的test.py脚本为例

python3 test.py --year 2021 --body [\"test\", \"robot\",\"boy\" ]

2021 ["test", "robot", "boy" ]

以方法1中的test.py脚本为例

python3 test.py [\"test\", \"robot\",\"boy\" ]

参数个数为: 2个参数。

参数列表: ['test.py', '[\"test\", \"robot\", \"boy\" ]']

脚本名: test.py

第一个参数: ["test", "robot", "boy" ]

其实此时传入的第一个参数是一个字符,需要转换为列表。

import json

json.loads(sys.argv[1])

test_arg.py脚本

#!/usr/bin/python3

import argparse

import os

# 生成了一个命令行参数的对象

parser = argparse.ArgumentParser(description='Test for argparse')

parser.add_argument('--body', '-b', help='body属性,必要参数', required=True)

args = parser.parse_args()

print (args.body)

command=python3 + '  ' + test_sys.py+ '  '  + args.body

print (command)

str=('command')

result=os.system(str)

test_sys.py脚本

#!/usr/bin/python3

import sys

import json

print ('第一个参数:', sys.argv[1])

print ('列表:', json.loads(sys.argv[1]))

执行python3 test_arg.py --body  [\"test\", \"robot\",\"boy\" ]

python3  test_sys.py  ["test", "robot", "boy" ]

test_sys.py执行报错,转json失败。

还记得我们案例2中,脚本的传入指定参数和实际传入参数嘛?

test_arg.py脚本我们稍微优化下,在传参前先字符替换下。

["test", "robot", "boy" ]转换为[\"test\", \"robot\",\"boy\" ]即可。

command.replace(' " ' , r ' \" ') 添加到command=之后,再次运行看看呢?