Python-函数传参与数据类型

news/2023/11/30 3:55:57

Python中,函数参数传递是通过对象的引用进行的,我们可以进行下面的验证。

def use_name(val):print("name id :%s" % (id(val)))val = "hanshu1"print("name id modified :%s" % (id(val)))def test_ref():name = "hanshu" print("name id :%s" % (id(name)))use_name(name)test_ref()

执行上面的代码,结果如下:

通过Python内置的id函数,用于获取对象的唯一id,它是对象的内存地址,会在创建时分配给对象。

因此,在use_name函数内和函数外,我们都得到了同样的id,说明函数在传递参数时,传递的是对象的引用。当我们给val重新赋值时,它的id也发生了变化,说明这个值是在内存上重新分配的。

函数传参既然是通过对象的引用进行,那么在函数内对对象进行修改,势必会影响到函数外。

那么哪些情况会影响到函数外,哪些不会呢?

Python的数据类型列表如下:

  • 数值型:包括整数(int)、浮点数(float)、复数(complex)等;

  • 字符串型:字符串,文本信息;

  • list(列表):用于存储一系列数据,可以是不同类型的数据;

  • set:存储一系列唯一的数据,不支持索引和切片操作;

  • tuple(元组):类似于列表,用来存储一系列数据,但是元组不可变,即不能修改元组中的元素;

  • dict(字典):以键值对的形式存储数据,用来表示映射关系;

  • bool(布尔值):表示真或假,取值为:True和False;

  • 自定义数据类型

这些数据类型创建的值分为不可变对象和可变对象。

 

顾名思义,对于不可变对象,在函数中,只能通过重新赋值来对其进行“修改”(这里实际上是重新创建);可变对象,在函数中,可以通过修改其暴露的数据成员来进行修改。

因此,在下面的代码中,当我们在函数内部修改dt参数时,函数外部也受到了影响。

def modify_dict(dt):dt["name"] = "item2"print("modify_dict:{}".format(dt))def test_dict():dt = { "name": "item1"}modify_dict(dt)print("dt:{}".format(dt))test_dict()

运行结果如下:

也就是说,如果是可变对象,在函数内部对其进行修改,会影响到函数外部。这里的修改,其实就是指通过对成员变量进行赋值或者调用其成员函数的方式改变对象的成员数据。

那么我们自定义的类型是可变对象还是不可变对象呢?

先看看下面的代码:

class MyItem:def __init__(self, val):self._data = valdef modify_my_item(my_item):my_item._data = 4print("my_item id:{}".format(id(my_item)))def test_my_item():my_item = MyItem(3)print("my_item._data = {}".format(my_item._data))print("my_item id:{}".format(id(my_item)))modify_my_item(my_item)print("my_item id:{}".format(id(my_item)))print("my_item._data = {}".format(my_item._data))

输出结果如下:

 

在函数内部修改了我们的自定义类型的字段,my_item的id一直没变,即对象本身没变,但是_data的值变了。

无赖Python中没有真正的私有成员变量,因此,我们的自定义类型也不可能做成不可变对象。因此,我们虽然在例子代码中,为了证明_data值发生了变化,而在modify_my_item被调用之后,再次去读取了_data的值,但是在实际项目中,我们应该尽量避免这么做。如果确实需要,那么要在传入对象的拷贝而非对象本身(这是比较昂贵的操作)。

代码我已经上传gitee

python_study: 用于学习Python语言和库功能特性

大家可以自己clone一个试试。使用命令运行:

git clone https://gitee.com/hanshu_alan/python_study.git
cd python_study/types_and_parameters
python main.py
cd python_study/param_as_ref
python main.py

代码在持续更新中,有问题欢迎留言交流。


https://www.xjx100.cn/news/3091593.html

相关文章

浪潮信息云峦服务器操作系统KeyarchOS体验与实践

写在前面 大家好我是网络豆,一名云计算运维人员,本文将会带大家体验一下浪潮信息服务器操作系统云峦KeyarchOS。看看浪潮信息服务器操作系统云峦KeyarchOS的优势与实践操作如何。 背景了解 KeyarchOS是浪潮信息基于Linux Kernel、OpenAnolis等开源技术…

Java 获取本地ip网卡信息

工具类 public static Optional<Inet4Address> getLocalIp4Address() throws SocketException {final List<Inet4Address> inet4Addresses getLocalIp4AddressFromNetworkInterface();if (inet4Addresses.size() ! 1) {final Optional<Inet4Address> ipBySo…

【Web】Ctfshow Nodejs刷题记录

目录 ①web334 ②web335 ③web336 ④web337 ⑤web338 ⑥web339 ⑦web340 ⑧web341 ⑨web342-343 ⑩web344 ①web334 进来是一个登录界面 下载附件&#xff0c;简单代码审计 表单传ctfshow 123456即可 ②web335 进来提示 get上传eval参数执行nodejs代码 payload: …

为什么mapper层不使用@Mapper注解,依然可以注入?

在MyBatis中&#xff0c;我们通常使用Mapper接口来操作数据库。在Spring Boot中&#xff0c;我们可以使用MapperScan注解来扫描Mapper接口所在的包&#xff0c;并将其注册到Spring容器中。但是&#xff0c;即使我们没有在Mapper接口上使用Mapper注解&#xff0c;Spring Boot也可…

nginx/html关闭网页缓存方法

【问题】 通常代理服务器默认是有缓存的&#xff0c;即用户访问网址的时候默认获取到的是缓存&#xff0c;只有刷新之后才能得到服务器端的最新文件 【解决】 以nginx为例&#xff0c;找到配置文件nginx.conf&#xff0c;找到http {}&#xff0c;在其花括号之内添加命令&…

同为科技(TOWE)智能机柜PDU助力上海华为数据中心完善机房末端配电

智能时代加速而来&#xff0c;最大的需求是算力&#xff0c;最关键的基础设施是数据中心。作为一家在信息通信领域拥有多年经验和技术积累的公司&#xff0c;华为在全国多个地区都设有数据中心&#xff0c;如知名的贵州贵安华为云全球总部、内蒙古乌兰察布华为数据中心等&#…

Python Web框架的三强之争:Flask、Django和FastAPI

JetBrains 公布 2022 Python 开发者调查结果。 完整报告地址&#xff1a;https://lp.jetbrains.com/zh-cn/python-developers-survey-2022/ 这是由 Python 软件基金会 (PSF) 和 JetBrains 共同开展的第六次官方年度 Python 开发者调查&#xff0c;回复于 2022 年 10 月至 12 …

探伤仪的曲线

超声波检验DAC曲线、AVG曲线的区别、使用及制作方法 一、 概念 1.1 DAC曲线 DAC距离波幅曲线是描述某一确定反射体回波高度随距离变化的关系曲线。因此&#xff0c;AVG曲线和DAC曲线都有纵波、横波制作的曲线&#xff0c;并不是简单地由纵波、横波来划分何为AVG曲线&#xf…