1. 如何理解Python中的深浅拷贝

浅拷贝(Shallow Copy)创建一个新的对象,该对象的内容是原始对象的引用。这意味着新对象与原始对象共享相同的内存地址,因此对于可变对象来说,如果修改了其中一个对象,另一个对象也会受到影响。浅拷贝通常使用copy模块的copy()函数或者对象的copy()方法来完成。

下面是一个浅拷贝的示例:

import copy

original_list = [1, 2, [3, 4]]
copied_list = copy.copy(original_list) print(original_list) # [1, 2, [3, 4]]
print(copied_list) # [1, 2, [3, 4]] # 修改原始列表中的元素
original_list[0] = 10
original_list[2][0] = 30 print(original_list) # [10, 2, [30, 4]]
print(copied_list) # [1, 2, [30, 4]]

在上面的示例中,copy.copy()函数创建了original_list的浅拷贝copied_list。当我们修改original_list时,copied_list中的嵌套列表也会受到影响。

深拷贝(Deep Copy)创建一个新的对象,该对象的内容是原始对象及其所有嵌套对象的副本。这意味着新对象在内存中是完全独立的,对其中一个对象的修改不会影响另一个对象。深拷贝通常使用copy模块的deepcopy()函数或者对象的deepcopy()方法来完成。

下面是一个深拷贝的示例:

import copy

original_list = [1, 2, [3, 4]]
deep_copied_list = copy.deepcopy(original_list) print(original_list) # [1, 2, [3, 4]]
print(deep_copied_list) # [1, 2, [3, 4]] # 修改原始列表中的元素
original_list[0] = 10
original_list[2][0] = 30 print(original_list) # [10, 2, [30, 4]]
print(deep_copied_list) # [1, 2, [3, 4]]

在上面的示例中,copy.deepcopy()函数创建了original_list的深拷贝deep_copied_list。即使我们修改original_listdeep_copied_list中的嵌套列表也不会受到影响。

需要注意的是,深拷贝可能会比浅拷贝更耗费时间和内存,因为它需要递归地复制所有嵌套对象。因此,在处理大型对象或嵌套层级很深的对象时,需要谨慎使用深拷贝。

总结起来,浅拷贝创建一个新对象,该对象与原始对象共享部分内存,而深拷贝创建一个完全独立的新对象,它复制了原始对象及其所有嵌套对象的内容。根据需求选择适当的拷贝方式可以帮助我们正确地处理对象并避免意外的副作用。

2.  谈谈 is 和 == 的区别:

在Python中,is==是用于比较对象的运算符,它们具有不同的功能和用途。

is运算符用于比较两个对象的身份标识,即它们是否指向同一个内存地址。如果两个对象具有相同的身份标识,即它们是同一个对象,那么is运算符返回True;否则,返回False

==运算符用于比较两个对象的值是否相等。它会比较两个对象的内容,而不关心它们是否指向同一个内存地址。如果两个对象的值相等,==运算符返回True;否则,返回False

下面是一个示例,展示了is==运算符的区别:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1 print(list1 is list2) # False,list1和list2不是同一个对象
print(list1 is list3) # True,list1和list3是同一个对象 print(list1 == list2) # True,list1和list2的值相等

在上面的示例中,list1list2虽然具有相同的值,但它们是不同的对象,因此list1 is list2返回False。另一方面,list1list3指向同一个对象,因此list1 is list3返回True。而list1 == list2返回True,因为它们的值相等。

需要注意的是,对于简单的值类型(如整数、字符串等),is==的结果通常是一致的。但对于可变对象(如列表、字典等),is==的结果可能不同,因为可变对象的身份标识可能相同,但值不同。

总结起来,is运算符用于比较两个对象的身份标识,即它们是否指向同一个内存地址;而==运算符用于比较两个对象的值是否相等。在编写代码时,需要根据具体的需求选择适当的运算符。如果要比较对象的值,应使用==运算符;如果要比较对象的身份标识,应使用is运算符。

3. 说说闭包和装饰器的概念:

**闭包(Closure)**是指在一个函数内部定义的函数,并且内部函数可以访问外部函数的变量。闭包可以捕获和保持外部函数的状态,即使外部函数已经执行完毕,内部函数仍然可以使用那些被捕获的变量。闭包在需要保持某些状态或者提供数据隐藏时非常有用。

下面是一个闭包的例子:

def outer_function(x):
def inner_function(y):
return x + y
return inner_function closure = outer_function(10)
result = closure(5)
print(result) # 输出 15

在上面的例子中,outer_function是外部函数,它接受一个参数x并返回一个内部函数inner_function。内部函数inner_function可以访问外部函数outer_function的参数x,即使在outer_function执行完毕后仍然有效。

**装饰器(Decorator)**是一种特殊的闭包,用于修改或增强函数的功能而不修改函数本身的定义。装饰器通常用于添加额外的代码,例如日志记录、性能分析、输入验证等。装饰器可以在不修改原函数代码的情况下,对函数进行包装和扩展。

下面是一个简单的装饰器的例子:

def logger(func):
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} executed.")
return result
return wrapper @logger
def add(a, b):
return a + b result = add(2, 3)
print(result) # 输出 5

在上面的例子中,logger是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数在调用被装饰的函数之前和之后打印日志信息。

通过使用@logger语法,我们将装饰器应用到add函数上。当调用add函数时,实际上是调用了被装饰后的wrapper函数,从而实现了日志记录的功能增强。

实际应用中,闭包和装饰器有许多用例。以下是一些示例:

  1. 计时器:使用装饰器记录函数的执行时间。
  2. 认证和权限控制:使用装饰器验证用户身份和控制访问权限。
  3. 缓存:使用闭包实现函数的结果缓存,以避免重复计算。
  4. 日志记录:使用装饰器将函数的调用和返回值记录到日志文件中。
  5. 输入验证:使用装饰器对函数的输入参数进行验证和过滤。

4. 用装饰器实现一个日志记录的例子:

def logger(func):
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__}")
print(f"Arguments: {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} executed.")
print(f"Result: {result}")
return result
return wrapper @logger
def add(a, b):
return a + b result = add(2, 3)

5. 可变对象和不可变对象有哪些:

**不可变对象(Immutable objects)**是指创建后不能被修改的对象。当对不可变对象进行操作时,会创建一个新的对象。以下是一些常见的不可变对象:

  1. **数字(Numbers)**:包括整数(int)、浮点数(float)、复数(complex)等。
  2. **布尔值(Booleans)**:True和False。
  3. **字符串(Strings)**:一旦创建,字符串的值就不能被修改。
  4. **元组(Tuples)**:元组是一种有序且不可变的集合。

以下是不可变对象的一些特点:

  • 不可变对象的值在创建后不能被修改,对其进行操作会创建一个新的对象。
  • 不可变对象在多线程环境下是线程安全的,因为其状态不可变。
  • 不可变对象可以作为字典的键或集合的元素,因为它们的哈希值不会变化。

**可变对象(Mutable objects)**是可以修改的对象,即可以改变对象的值或状态。以下是一些常见的可变对象:

  1. **列表(Lists)**:列表是有序且可变的集合,可以通过索引进行修改。
  2. **字典(Dictionaries)**:字典是无序的键值对集合,可以通过键进行修改。
  3. **集合(Sets)**:集合是无序且唯一的元素集合,可以进行添加、删除等操作。

以下是可变对象的一些特点:

  • 可变对象的值可以在创建后被修改,对其进行操作会直接修改原始对象。
  • 可变对象在多线程环境下需要进行同步操作,以避免并发修改导致的问题。
  • 可变对象不能作为字典的键或集合的元素,因为其值的变化可能导致哈希值的变化。

6. 什么是值传递和引用传递:

**值传递(Pass-by-Value)**是指将实际参数的值复制一份,传递给函数或赋值给新变量。在这种情况下,函数或新变量操作的是复制后的值,对原始变量的修改不会影响到原始值。

**引用传递(Pass-by-Reference)**是指将实际参数的引用或地址传递给函数或赋值给新变量。在这种情况下,函数或新变量操作的是原始变量所在的内存地址,对变量的修改会直接影响到原始值。

在Python中,参数传递是通过引用传递的方式进行的。也就是说,函数或方法的参数传递的是对象的引用,而不是对象本身的副本。这意味着,如果在函数内部对引用的对象进行修改,会影响到原始对象。

下面是一个示例:

def modify_list(lst):
lst.append(4) my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # 输出 [1, 2, 3, 4]

在上面的例子中,我们定义了一个modify_list函数,它接受一个列表作为参数并向列表中添加一个元素。当我们调用modify_list(my_list)时,实际上是将my_list的引用传递给modify_list函数。在函数内部,我们通过引用对列表进行修改,添加了一个新元素。这导致原始列表my_list也被修改,输出结果为[1, 2, 3, 4]

在实际使用中,我们需要根据需求选择值传递还是引用传递。一般来说,如果希望在函数内部修改原始对象,可以使用引用传递。如果希望保持原始对象不变,可以使用值传递或传递对象的副本。

需要注意的是,在Python中,虽然参数传递是通过引用传递的方式,但对于不可变对象(如整数、字符串、元组),因为其值无法修改,所以表现类似于值传递。而对于可变对象(如列表、字典、集合),因为其值可以修改,所以表现类似于引用传递。

值传递例子:

def modify_value(value):
value = value + 1 x = 10
modify_value(x)
print(x) # 输出 10

在上面的例子中,我们定义了一个modify_value函数,它接受一个整数参数value。在函数内部,我们对value进行加1操作。然而,即使在函数内部对value进行了修改,原始变量x的值并没有改变。这是因为整数是不可变对象,函数调用时发生的是值传递,传递的是x的值的副本,而不是x本身

 

python 面试题第一弹的更多相关文章

  1. python面试题第一份

    阅读目录 1 Python的函数参数传递 2 Python中的元类(metaclass) 3 @staticmethod和@classmethod 4 类变量和实例变量 5 Python自省 6 字典 ...

  2. python数据类型(第一弹)

    作为一门计算机编程语言,python与其它语言一样,设有若干种数据类型,准确掌握各种数据类型的常用方法是精通python的必要条件,也是熟练使用各数据类型.最大限度发挥它们功能的基本条件. pytho ...

  3. 03.Python网络爬虫第一弹《Python网络爬虫相关基础概念》

    爬虫介绍 引入 之前在授课过程中,好多同学都问过我这样的一个问题:为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的 ...

  4. Python网络爬虫第一弹《Python网络爬虫相关基础概念》

    爬虫介绍 引入 之前在授课过程中,好多同学都问过我这样的一个问题:为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的 ...

  5. 03,Python网络爬虫第一弹《Python网络爬虫相关基础概念》

    爬虫介绍 引入 为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的应用还是从就业上. 我们都知道,当前我们所处的时代 ...

  6. JS面试题第一弹

    1.javascript的typeof返回哪些数据类型  alert(typeof [1, 2]); //object     alert(typeof 'leipeng'); //string   ...

  7. python公司面试题集锦 python面试题大全

    问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...

  8. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  9. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  10. 【Python】【面试必看】Python笔试题

    前言 现在面试测试岗位,一般会要求熟悉一门语言(python/java),为了考验求职者的基本功,一般会出 2 个笔试题,这些题目一般不难,主要考察基本功.要是给你一台电脑,在编辑器里面边写边调试,没 ...

随机推荐

  1. Redash 可视化BI系统部署安装及简单使用

    这篇文章主要为介绍一下Redash的使用和安装 概览 Redash 主要使用的语言为 Python 和 TypeScript 这个安装主要是基于Docker 来安装的,官网教程基本没有不是基于Dock ...

  2. django购物车的实现

    1 购物车的实现问题思路 购物车需求分析: 1 未登陆和已登陆都保存到用户的购物车数据. 2 用户可以对购物车进行增删改查: 3 购物车有选择状态,只有选中的状态才能生成订单: 4 用户登陆时,合并c ...

  3. AI 协助办公 |记一次用 GPT-4 写一个消息同步 App

    GPT-4 最近风头正劲,作为 NebulaGraph 的研发人员的我自然是跟进新技术步伐.恰好,现在有一个将 Slack channel 消息同步到其他 IM 的需求,看看 GPT-4 能不能帮我完 ...

  4. 消失的死锁:从 JSF 线程池满到 JVM 初始化原理剖析

    一.问题描述 在一次上线时,按照正常流程上线后,观察了线上报文.接口可用率十分钟以上,未出现异常情况,结果在上线一小时后突然收到jsf线程池耗尽的报警,并且该应用一共有30台机器,只有一台机器出现该问 ...

  5. 无限分解流----Fork/Join框架

    Fork译为拆分,Join译为合并Fork/Join框架的思路是把一个非常巨大的任务,拆分成若然的小任务,再由小任务继续拆解.直至达到一个相对合理的任务粒度.然后执行获得结果,然后将这些小任务的结果汇 ...

  6. 免杀系列之利用blockdlls和ACG保护恶意进程

    blockdlls Cobalt Strike 3.14版本以后添加了blockdlls功能,它将创建一个子进程并限定该子进程只能加载带有Microsoft签名的DLL. 这个功能可以阻止第三方安全软 ...

  7. Spring 的依赖注入(DI)

    前言 欢迎来到本篇文章,书接上回,本篇说说 Spring 中的依赖注入,包括注入的方式,写法,该选择哪个注入方式以及可能出现的循环依赖问题等内容. 如果正在阅读的朋友还不清楚什么是「依赖」,建议先看看 ...

  8. 聊聊 RocketMQ 主从复制

    提到主从复制,我们可能立马会联想到 MySQL 的主从复制. MySQL 主从复制是 MySQL 高可用机制之一,数据可以从数据库服务器主节点复制到一个或多个从节点. 这篇文章,我们聊聊 Rocket ...

  9. Python与MySQL如何保持长连接

    Python与MySQL如何保持长连接 介绍 在python后端开发中,时常会与数据库交互,重复的断开.连接 会大大消耗数据库资源. 所以一般都是定义全局变量,来弥补这个缺陷. 但是 Python 与 ...

  10. 基于GPT搭建私有知识库聊天机器人(四)问答实现

    前文链接: 基于GPT搭建私有知识库聊天机器人(一)实现原理 基于GPT搭建私有知识库聊天机器人(二)环境安装 基于GPT搭建私有知识库聊天机器人(三)向量数据训练 在前面的文章中,我们介绍了如何使用 ...