目录
🍔 你知道深浅拷⻉的区别吗?
🍔 字典反转,列表反转的实现?
🍔 装饰器是什么,什么场景⽤到装饰器,举个例⼦?
🍔 装饰器的实质是什么?
🍔 Python迭代器是什么?什么场景⽤到迭代器?举⼀个例⼦?
🍔 Python⽣成器是什么?什么场景⽤到迭代器?举⼀个例⼦?
🍔 Python多线程与多进程的区别是什么?
🍔 请写⼀段Python代码实现删除⼀个list⾥⾯的重复元素
🍔 请设计⼀个decorator,它可作⽤于任何函数上,并打印该函 数的执⾏时间。
🍔 装饰器的实质是什么?
🍔 你知道深浅拷⻉的区别吗?
- 浅拷⻉: 拷⻉的是对象的引⽤,如果原对象改变,相应的拷⻉对象也会发⽣改变
- 深拷⻉: 拷⻉对象中的每个元素,拷⻉对象和原有对象不在有关系,两个是独⽴的对象
- 直接赋值:其实就是对象的引⽤(别名)。
- 浅拷⻉(copy):拷⻉⽗对象,不会拷⻉对象的内部的⼦对象。
- 深拷⻉(deepcopy): copy 模块的 deepcopy ⽅法,完全拷⻉了⽗对象及其⼦对象。
🍔 字典反转,列表反转的实现?
- 列表的反转:reversed 函数、sorted函数、切⽚技术、循环,递归,四种⽅式
- 字典的反转:循环,推导式,压缩器三种⽅式
列表反转:
字典反转:
🍔 装饰器是什么,什么场景⽤到装饰器,举个例⼦?
装饰器(Decorator)是⼀种结构型设计模式,它可以动态地给⼀个对象添加额外的职责,同时⼜不改变其原有的接⼝和实现。通俗地说,就是通过组合的⽅式,为对象添加新的⾏为或特性。在Python语⾔中,装饰器是⼀种语法糖,可以通过定义函数或类来实现。装饰器可以⽤于很多场景。
场景举例:1)⽇志记录:可以定义⼀个装饰器函数,⽤于在函数调⽤时记录⽇志信息,如函数的参数、返回值等。2)性能分析:可以定义⼀个装饰器函数,⽤于在函数调⽤时计算函数的执⾏时间,以便进⾏性能优化。3)权限校验:可以定义⼀个装饰器函数,⽤于在函数调⽤时进⾏⽤户权限校验,以确保只有具有相应权限的⽤户可以访问该函数。
下⾯是⼀个装饰器的例⼦,⽤于记录函数的执⾏时间:
import time
def time_it(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数 {func.__name__} 执⾏时间为:{end_time - start_time} 秒")
return result
return wrapper
@time_it
def my_function():
time.sleep(2)
print("Hello, World!")
my_function()
在这个例⼦中,我们定义了⼀个装饰器函数 time_it ,它接受⼀个函数作为参数,并返回⼀个新的函数 wrapper 。 wrapper 函数可以记录函数执⾏前后的时间,并输出执⾏时间信息。在 my_function 函数前⾯加上 @time_it 装饰器,表示对 my_function 函数应⽤ time_it 装饰器。当调⽤ my_function 函数 时,实际上会调⽤被 time_it 装饰过的 wrapper 函数,从⽽记录函数的执⾏时间。
🍔 装饰器的实质是什么?
装饰器实质:装饰器是要把原来的函数装饰成新的函数,并且返回这个函数本身的⾼阶函数。
🍔 Python迭代器是什么?什么场景⽤到迭代器?举⼀个例⼦?
迭代器(Iterator)是⼀个可以迭代访问序列元素的对象。
迭代器对象实现了两个⽅法:
__iter__()和__next__()。
- __iter__()⽅法返回迭代器对象本身
- __next__()⽅法返回下⼀个元素。
迭代器常⽤于遍历序列、集合、字典等容器类型数据。
它的优点是可以惰性计算(lazy evaluation),即 只有在需要时才会计算,避免了⼀次性加载所有数据的开销,同时也可以节省内存空间。
使⽤迭代器通常有以下场景:
- 遍历⼤量数据集合:当需要处理⼤量的数据集合时,使⽤迭代器可以避免⼀次性加载所有数据,节省 内存空间。
- 实现⾃定义迭代器:当需要遍历⾃定义数据结构时,可以通过实现迭代器对象的__iter__()和 __next__()⽅法来实现⾃定义迭代器。
- 实现惰性计算:当需要进⾏惰性计算时,可以使⽤迭代器来实现,例如通过filter()、map()等⾼阶函 数返回⼀个迭代器对象来进⾏惰性计算。
下⾯是⼀个使⽤迭代器遍历列表的例⼦:
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
while True:
try:
item = next(my_iterator)
print(item)
except StopIteration:
break
在这个例⼦中,我们通过 iter() 函数将列表 my_list 转化为⼀个迭代器对象 my_iterator ,然后使⽤ while 循 环和 next() 函数来依次访问迭代器中的元素。当所有元素都被访问完毕时,迭代器会抛出 StopIteration 异常,这时我们就可以跳出循环。
🍔 Python⽣成器是什么?什么场景⽤到迭代器?举⼀个例⼦?
⽣成器(Generator)是⼀种特殊的迭代器,它使⽤⽣成器函数来⽣成序列中的元素,⽽不 是在内存中⼀次性⽣成所有元素。
⽣成器函数是使⽤yield关键字定义的函数,每次调⽤⽣成器函数时,它会返回⼀个迭代器对象,调⽤ next()⽅法时,它会从上次暂停的位置继续执⾏,直到遇到下⼀个yield语句,然后返回⼀个值,并再次暂 停。因此,⽣成器可以惰性地⽣成序列中的元素,并在需要时逐个⽣成元素,避免了⼀次性⽣成所有元 素所带来的内存消耗。
使⽤⽣成器的场景包括:
- ⽣成⼤量的数据集合:当需要⽣成⼤量数据时,使⽤⽣成器可以避免⼀次性占⽤⼤量内存空间。
- 实现⾃定义的迭代器:当需要⾃定义迭代器对象时,可以使⽤⽣成器函数来实现,避免了繁琐的迭代 器对象的定义。
- 实现惰性计算:当需要进⾏惰性计算时,可以使⽤⽣成器来实现,例如通过filter()、map()等⾼阶函 数返回⼀个⽣成器对象来进⾏惰性计算。
下⾯是⼀个使⽤⽣成器函数⽣成斐波那契数列的例⼦:
def fibonacci(n):
a, b = 0, 1
for i in range(n):
yield a
a, b = b, a + b
fib = fibonacci(10)
for num in fib:
print(num)
在这个例⼦中,我们定义了⼀个⽣成器函数 fibonacci() ,它的参数 n 表示需要⽣成的斐波那契数列的⻓度。在函数中,我们使⽤ yield 语句返回斐波那契数列中的每⼀个元素,这样每次调⽤ next() 函数时,它会返回下⼀个元素,并在下次调⽤时从上次暂停的位置继续执⾏。最后,我们使⽤ for 循环遍历⽣成器对象,并打印出每个元素。
🍔 Python多线程与多进程的区别是什么?
- 在UNIX平台上,当某个进程终结之后,该进程需要被其⽗进程调⽤wait,否则进程成为僵⼫进程 (Zombie)。
- 所以,有必要对每个Process对象调⽤join()⽅法 (实际上等同于wait)。对于多线程来说, 由 于只有⼀个进程,所以不存在此必要性。
- 多进程应该避免共享资源。在多线程中,我们可以⽐较容易地共享资源,⽐如使⽤全局变量或者传 递参 数。在多进程情况下,由于每个进程有⾃⼰独⽴的内存空间,以上⽅法并不合适。
- 此时我们可 以通过共 享内存和Manager的⽅法来共享资源。但这样做提⾼了程序的复杂度,并因为同步的需要⽽降低了程序的效率。
🍔 请写⼀段Python代码实现删除⼀个list⾥⾯的重复元素
主要⽤到了set()函数。
l = [1,1,2,3,4,5,4]>>> list(set(l))>>> [1, 2,3,4,5]
代码演示:
mylist=[1,1,2,3,4,5,4]
d = {}
for x in mylist:
d[x] = 1
mylist = list(d.keys())
print(mylist)
🍔 请设计⼀个decorator,它可作⽤于任何函数上,并打印该函 数的执⾏时间。
# -*- coding: utf-8 -*-
import time, functoolsdef metric(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
time0 = time.time()
ret = fn(*args, **kw)
time1 = time.time()
print('%s executed in %s ms' % (fn.__name__, time1-time0))
return ret
return wrapper
🍔 装饰器的实质是什么?
或者说为什么装饰器要写2层嵌套函数,⾥层函数完全就已经实现了装饰的功能为什么不直接⽤⾥层函数名作为装饰器名称?
答:装饰器是要把原来的函数装饰成新的函数,并且返回这个函数本身的⾼阶函数
💘若能为您的学习之旅添一丝光亮,不胜荣幸💘
🐼期待您的宝贵意见,让我们共同进步共同成长🐼