赞
踩
目录
浅拷贝得到的对象与原始对象共享一块内存地址,当一个对象发生改变时,另一个也会发生改变。可以使用切片,copy.copy(),list()等完成浅拷贝。
深拷贝是指创建一个全新的对象,与原始对象互不干扰。可以使用copy.deepcopy().
因为python每个进程会有一个全局解释器锁的存在(GIL),全局(包括多个cpu)只有一个线程可以占用这个锁。这使得每个python进程只能在一个cpu上运行。那么就有人问了,既然多线程起不到作用,为什么还要用那,那是因为还存在线程阻塞的问题,对于密集i/o操作,网络请求等阻塞型任务时,当一个线程被阻塞了,他可以释放GIL,让其他线程继续工作,可以适当加速,所以还是有用的。
那么我们如何解决GIL的问题?可以使用多进程,每个进程都有各自独立的GIL锁,互不影响。使用其他python解释器,如PYPY。
对于密集IO操作,一般用多线程,对于密集计算型任务,一般使用多进程。多线程共享一个内存空间,所以信息传输更加简单。
python的垃圾回收机制会自动处理对象的内存分配和释放问题。一般有两种回收机制:一种是引用计数,python里的每个对象都有一个计数器,用于记录指向该对象的引用次数,当变为0时,会自动释放。还有一种循环垃圾回收机制,循环引用是指一组对象相互引用形成闭环,且没有任何外部引用指向这个闭环,这时使用循环垃圾回收机制,周期性的检测清理,在进行垃圾回收时,首先会对当前所有对象进行标记,然后回收那些未被标记的对象。这样就会清除掉循环引用等无法通过引用计数判断的对象。
迭代器和生成器是python中用于处理可迭代对象的两种不同机制。迭代器学要手动实现__iter__和__next__方法,并在next中定义迭代逻辑。生成器是一种特殊的函数,每次调用生成器时,他会保存当前的执行状态,并在yield语句处暂停,下次再次调用时,会从上次结束的位置继续执行,直到函数结束或遇到下一个yield。生成器简化了迭代器的创建过程,适用于惰性计算。而迭代器适用于复杂的迭代逻辑。生成器可以节省内存,因为它在运行时只保留当前的状态,而不是一次性生成所有值。
当生成器函数被调用时,它并不立即执行,而是返回一个生成器对象。每当生成器的 __next__()
方法被调用时,生成器函数才会从上次暂停的地方继续执行,直到遇到下一个 yield
语句
- def fibonacci(): //生成器函数
- a, b = 0, 1
- while True:
- yield a
- a, b = b, a + b
-
- # 使用生成器逐个打印斐波那契数列的前十个数
- fib = fibonacci()
- for _ in range(10):
- print(next(fib))
- class MyIterator:
- def __init__(self, data):
- self.data = data
- self.index = 0
-
- def __iter__(self):
- return self
-
- def __next__(self):
- if self.index >= len(self.data):
- raise StopIteration
- value = self.data[self.index]
- self.index += 1
- return value
-
- # 创建一个列表
- my_list = [1, 2, 3, 4, 5]
-
- # 创建一个迭代器对象
- my_iter = MyIterator(my_list)
-
- # 使用迭代器遍历列表并打印每个元素
- for item in my_iter:
- print(item)

my_iter是一个迭代器对象,使用for循环对其进行遍历,每次得到的值,都为next中处理后返回的。
装饰器是一种特殊的函数,用来扩展,包装和修改函数,而无需改变其原始定义。通常采用函数嵌套的形式,接受一个函数作为参数。通过闭包来实现装饰器的定义。
- def counter(func):
- count = 0
-
- def wrapper(*args, **kwargs):
- nonlocal count
- count += 1
- print(f"函数 {func.__name__} 已被调用 {count} 次")
- return func(*args, **kwargs)
-
- return wrapper
-
- # 使用装饰器修饰目标函数
- @counter
- def say_hello(name):
- print(f"Hello, {name}!")
-
- # 调用被修饰的函数
- say_hello("Alice")
- say_hello("Bob")

字符串(string)
列表类型(list)用[]中括号表示。
元组类型(tuple):用小括号表示。
字典类型(dict):{},键值之间用冒号,不同键值对之间用逗号。
集合(set):{}。
del通过索引删除指定位置的元素,或者全部删除。
remove通过值来删除列表中第一个匹配项。
pop通过索引来删除元素,并返回值。
- my_list = [1, 2, 3, 4, 5]
- del my_list[2] # 删除索引为2的元素
- print(my_list) # 输出:[1, 2, 4, 5]
-
- del my_list # 删除整个列表
-
- # 注意:使用 del 关键字删除的元素是永久性删除,不可恢复。
-
-
-
- my_list = [1, 2, 3, 4, 5]
- my_list.remove(3) # 删除值为3的元素
- print(my_list) # 输出:[1, 2, 4, 5]
-
- # 如果要删除多个匹配项,需要循环调用 remove 方法。
-
-
- my_list = [1, 2, 3, 4, 5]
- value = my_list.pop(2) # 删除索引为2的元素,并返回该元素的值
- print(my_list) # 输出:[1, 2, 4, 5]
- print(value) # 输出:3
-
- # 如果不指定索引,pop 方法默认删除最后一个元素,并返回其值。

return会结束函数的执行,而yield会返回一个值,并暂停函数的执行,然后记住函数的执行状态,以便从暂停处继续执行。
可哈希对象可以作为字典的键或集合的元素,其包含:数值类型,字符串,元组。不可哈希对象包含:列表,字典,集合
字典的排序需要用到items()方法,根据值来操作,则需要lambda函数
- my_dict = {'apple': 5, 'banana': 2, 'orange': 8, 'kiwi': 3}
- my_dict = dict(sorted(my_dict.items(), key = lambda x : x[1]))
lambda函数是一种匿名函数,可以在需要一个简单的函数时使用。后面跟着参数列表和冒号,冒号后面是函数表达式,这个表达式的结果作为lambda的返回值。
- # 使用 lambda 函数计算两个数的和
- sum_func = lambda a, b: a + b
-
- result = sum_func(3, 4)
- print(result)
__new__方法:是一个对象实例化之前被调用的方法,他负责创建并返回一个实例对象。参数列表中至少有一个必须是类本身
__init__方法:是一个对象实例化之后调用的方法,它用于对实例对象进行属性的初始化设置。参数列表中至少有一个必须是实例对象,通常被命名为self。
__call__方法:使得一个对象可以像函数一样被调用。当将对象作为函数调用时,会触发__call__
方法。
引用计数和循环垃圾回收机制。迭代器和生成器按需生成数据,而不是一次性生成所有结果。
在 Python 中,类方法(class method)和静态方法(static method)都是类中定义的特殊方法,但它们在功能和使用方式上有一些区别。
@classmethod
装饰器来修饰方法,使之成为类方法。cls
,指向类本身,可以通过该参数访问类的属性和调用类的其他方法。@staticmethod
装饰器来修饰方法,使之成为静态方法。cls
可以访问类的属性和调用类的其他方法,主要用于执行与类相关的操作。- class MyClass:
- @classmethod
- def class_method(cls):
- print("This is a class method")
-
- # 调用类方法
- MyClass.class_method()
-
-
-
-
- class MyClass:
- @staticmethod
- def static_method():
- print("This is a static method")
-
- # 调用静态方法
- MyClass.static_method()

- import threading
-
- # 定义一个函数作为线程的执行体
- def my_thread():
- print("Thread started.")
-
- # 创建 10 个线程
- threads = []
- for i in range(10):
- thread = threading.Thread(target=my_thread)
- thread.start()
- threads.append(thread)
-
- # 等待所有线程执行完毕
- for thread in threads:
- thread.join()
-
- print("All threads are done.")

在上面的代码中,我们创建了一个线程列表 threads
,然后通过循环创建了 10 个线程,并将它们添加到列表中。每个线程都通过调用 start()
方法启动并开始执行。接着,我们使用另一个循环遍历线程列表,并调用每个线程的 join()
方法,程序会在该方法处阻塞,直到该线程执行完毕才继续执行下一行代码。这样可以确保主线程在所有子线程完成后再继续执行。
- import multiprocessing
-
- # 定义一个函数作为进程的执行体
- def my_process():
- print("Process started.")
-
- # 创建 10 个进程
- processes = []
- for i in range(10):
- process = multiprocessing.Process(target=my_process)
- process.start()
- processes.append(process)
-
- # 等待所有进程执行完毕
- for process in processes:
- process.join()
-
- print("All processes are done.")

主要根据参数是可变对象还是不可变对象来说。对于不可变对象,如数值类型,字符串,元组,是值传递,不会影响原始参数。
对于可变对象,如列表,字典,集合等,是引用传递,会直接在原始对象上操作。
是指在运行时,动态修改已有的代码或者类成员。
- class MyClass:
- def method(self):
- print("Original method")
-
- # 定义新方法
- def new_method(self):
- print("Patched method")
-
- # 将新方法绑定到原始类
- MyClass.method = new_method
-
- # 创建对象并调用方法
- obj = MyClass()
- obj.method() # 输出: "Patched method"
is是判断两个对象是否引用了内存中的同一块地址。 == 是判断两者的值是否相等。
列表生成式 [i for i in range(n)]
字典生成式(元组变为字典) {x[0] : x[1] for x in turple}
列表切片反转 [::-1]
在python2中range()函数会返回一个列表类型,python3会返回一个迭代器。仅在需要的时候才会计算下一个元素,占用内存更少,可以用list(range(n))直接使用。
它可以使当前目录被视为一个包,并提供了进行初始化和控制导入行为的能力,他是构建和组织复杂项目的重要组成部分。__init__.py
文件还可以通过定义 __all__
变量来控制包的导入行为。__all__
是一个列表,指定了在使用 from package import *
语句导入包时,应该导入哪些子模块或对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。