国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

福永網(wǎng)站設(shè)計(jì)多少錢seo入門免費(fèi)教程

福永網(wǎng)站設(shè)計(jì)多少錢,seo入門免費(fèi)教程,南昌網(wǎng)站建設(shè)優(yōu)化,網(wǎng)頁設(shè)計(jì)與制作教程第二版知識(shí)點(diǎn)總結(jié)1. 可變對(duì)象和不可變對(duì)象 (1). 不可變對(duì)象( Immutable Objects ) 不可變對(duì)象指的是那些一旦創(chuàng)建后其內(nèi)容就不能被修改的對(duì)象。如果嘗試修改不可變對(duì)象的內(nèi)容,將會(huì)創(chuàng)建一個(gè)新的對(duì)象而不是修改原來的對(duì)象。常見的不可變類型包括: …
1. 可變對(duì)象和不可變對(duì)象
(1). 不可變對(duì)象( Immutable Objects

不可變對(duì)象指的是那些一旦創(chuàng)建后其內(nèi)容就不能被修改的對(duì)象。如果嘗試修改不可變對(duì)象的內(nèi)容,將會(huì)創(chuàng)建一個(gè)新的對(duì)象而不是修改原來的對(duì)象。常見的不可變類型包括:

  • 數(shù)字類型: int, float, complex
  • 字符串: str
  • 元組: tuple
  • 凍結(jié)集合: frozenset

可以理解為對(duì)象的內(nèi)容一旦修改(改變),對(duì)象的內(nèi)存地址改變

s = "Hello"
print(id(s))  # 輸出原始字符串的內(nèi)存地址s += ", World!"
print(id(s))  # 輸出新字符串的內(nèi)存地址,與之前不同
(2). 可變對(duì)象

可變對(duì)象是指在其創(chuàng)建之后還可以對(duì)其內(nèi)容進(jìn)行修改的對(duì)象。這意味著你可以在不改變對(duì)象身份的情況下更改它的內(nèi)容。常見的可變類型包括:

列表: list
字典: dict
集合: set
**自定義類實(shí)例:**除非特別設(shè)計(jì)為不可變

lst = [1, 2, 3]
print(id(lst))  # 輸出列表的內(nèi)存地址
lst.append(4)
print(id(lst))  # 內(nèi)存地址保持不變,說明是原地修改
2. @staticmethod和@classmethod
(1). @staticmethod

定義:使用@staticmethod裝飾的方法不接受隱式的第一個(gè)參數(shù)(如selfcls。這意味著這些方法既不能訪問實(shí)例屬性也不能訪問類屬性。

用途:通常用于那些與類有關(guān)但不需要訪問類或?qū)嵗齼?nèi)部數(shù)據(jù)的功能。 這樣的方法更像是普通的函數(shù),只是由于組織上的原因被放在了類中。

特點(diǎn):

  • 不能訪問實(shí)例屬性: 由于靜態(tài)方法沒有self參數(shù),所以無法訪問任何與特定對(duì)象實(shí)例相關(guān)的屬性。
  • 不能訪問類屬性: 同樣地,因?yàn)闆]有cls參數(shù),靜態(tài)方法也無法直接訪問類級(jí)別的屬性。
class Example:class_var = "I am a class variable"  # 類變量def __init__(self, value):self.instance_var = value  # 實(shí)例變量@staticmethoddef static_method():# 下面這兩行會(huì)導(dǎo)致錯(cuò)誤,因?yàn)殪o態(tài)方法無法訪問實(shí)例或類屬性# print(self.instance_var)  # AttributeError: 'staticmethod' object has no attribute 'instance_var'# print(class_var)  # NameError: name 'class_var' is not definedprint("This is a static method.")def instance_method(self):print(f"Instance variable: {self.instance_var}")print(f"Class variable: {Example.class_var}")# 創(chuàng)建實(shí)例
ex = Example("I am an instance variable")# 調(diào)用靜態(tài)方法
Example.static_method()  # 輸出: This is a static method.# 調(diào)用實(shí)例方法
ex.instance_method()
# 輸出:
# Instance variable: I am an instance variable
# Class variable: I am a class variable

在這個(gè)例子中,my_static_method是一個(gè)靜態(tài)方法,它可以直接通過類名調(diào)用,不需要?jiǎng)?chuàng)建類的實(shí)例

(2). @classmethod

定義: 使用@classmethod裝飾的方法接收一個(gè)隱含的第一個(gè)參數(shù),這個(gè)參數(shù)通常是cls,代表類本身。因此,類方法可以訪問和修改類級(jí)別的屬性,也可以調(diào)用其他類方法

用途: 常用于需要操作類級(jí)別數(shù)據(jù)的方法,或者當(dāng)你需要從該方法返回類的不同子類時(shí)很有用。

示例 1: 訪問和修改類級(jí)別屬性

假設(shè)我們有一個(gè)Person類,其中包含一個(gè)類級(jí)別的屬性count,用于記錄創(chuàng)建了多少個(gè)Person對(duì)象。我們可以使用類方法來更新這個(gè)計(jì)數(shù)器。

class Person:count = 0  # 類變量,用于跟蹤創(chuàng)建了多少個(gè)Person對(duì)象def __init__(self, name):self.name = namePerson.count += 1  # 每當(dāng)創(chuàng)建一個(gè)新的實(shí)例時(shí)增加計(jì)數(shù)@classmethoddef get_count(cls):return cls.count  # 使用cls訪問類變量# 創(chuàng)建一些Person實(shí)例
p1 = Person("Alice")
p2 = Person("Bob")
# 使用類方法獲取當(dāng)前的計(jì)數(shù)
print(Person.get_count())  # 輸出應(yīng)該是2,因?yàn)閯?chuàng)建了兩個(gè)實(shí)例

在這個(gè)例子中,get_count是一個(gè)類方法,它可以通過cls訪問類級(jí)別的屬性count,而無需實(shí)例化Person類。

示例 2: 提供替代構(gòu)造函數(shù)

有時(shí)候,你可能希望提供多種方式來創(chuàng)建類的實(shí)例。你可以利用類方法作為“工廠方法”,為不同的需求提供不同的構(gòu)造邏輯

class Date:def __init__(self, year, month, day):self.year = yearself.month = monthself.day = day@classmethoddef from_string(cls, date_string):year, month, day = map(int, date_string.split('-'))return cls(year, month, day)  # 返回一個(gè)新實(shí)例# 使用標(biāo)準(zhǔn)構(gòu)造函數(shù)
date1 = Date(2023, 4, 1)# 使用類方法提供的替代構(gòu)造函數(shù)
date2 = Date.from_string("2023-04-01")print(date1.year, date1.month, date1.day)  # 輸出:2023 4 1
print(date2.year, date2.month, date2.day)  # 輸出:2023 4 1

這里,from_string類方法允許用戶從字符串格式的數(shù)據(jù)創(chuàng)建Date對(duì)象,這增加了靈活性。

示例 3: 調(diào)用其他類方法

類方法還可以調(diào)用其他的類方法或靜態(tài)方法,這在需要鏈?zhǔn)讲僮骰蛘邚?fù)用已有邏輯的情況下非常有用。

class MathOperations:@classmethoddef add(cls, a, b):return a + b@classmethoddef multiply(cls, a, b):return a * b@classmethoddef combined_operation(cls, a, b):sum_result = cls.add(a, b)product_result = cls.multiply(a, b)return sum_result, product_resultresult = MathOperations.combined_operation(5, 3)
print(result)  # 輸出:(8, 15),分別是加法和乘法的結(jié)果

在上面的例子中,combined_operation類方法內(nèi)部調(diào)用了另外兩個(gè)類方法addmultiply來完成一系列計(jì)算。

3. 迭代器和生成器
(1) 迭代器(Iterator

迭代器是一個(gè)可以記住遍歷位置的對(duì)象,它從集合的第一個(gè)元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會(huì)后退。Python中,要?jiǎng)?chuàng)建一個(gè)迭代器對(duì)象,需要實(shí)現(xiàn)兩個(gè)方法:__iter__()__next__()

(1.1) 內(nèi)置迭代器:

序列迭代器: 列表、元組、字符串等序列類型都有默認(rèn)的迭代器。

my_list = [1, 2, 3]
iterator = iter(my_list)
print(next(iterator))  # 輸出: 1

字典視圖迭代器:.keys(), .values(), .items()返回的都是迭代器對(duì)象。

python
深色版本
my_dict = {'a': 1, 'b': 2}
keys_iterator = iter(my_dict.keys())
print(next(keys_iterator))  # 輸出: 'a'

文件迭代器: 打開的文件對(duì)象也是迭代器,可用于逐行讀取文件內(nèi)容。

with open('example.txt', 'r') as file:for line in file:print(line.strip())
(1.2) 自定義迭代器
  • iter():返回迭代器對(duì)象本身。
  • next():返回容器中的下一個(gè)值。如果沒有更多的元素可供返回,則拋出 StopIteration 異常。 迭代器的一個(gè)重要特性是可以節(jié)省內(nèi)存,因?yàn)樗恍枰淮涡约虞d整個(gè)數(shù)據(jù)集到內(nèi)存中,而是按需生成數(shù)據(jù)。
class MyIterator:def __init__(self, max_value):self.max_value = max_valueself.current = 0def __iter__(self):return selfdef __next__(self):if self.current < self.max_value:value = self.currentself.current += 1return valueelse:raise StopIteration# 使用自定義迭代器
my_iter = MyIterator(3)
for i in my_iter:print(i)  # 輸出: 0, 1, 2
(2) 生成器(Generator
(2.1) 生成器函數(shù)

生成器是一種特殊的迭代器,它是通過函數(shù)來創(chuàng)建的,但是與普通函數(shù)不同的是,生成器使用了 yield 關(guān)鍵字而不是 return。每當(dāng)生成器函數(shù)執(zhí)行到 yield 語句時(shí),它會(huì)暫停并保存當(dāng)前的所有狀態(tài),然后返回 yield 的值給調(diào)用者。當(dāng)后續(xù)再次調(diào)用生成器時(shí),它會(huì)從上次離開的地方繼續(xù)執(zhí)行 。這種機(jī)制使得生成器非常適合處理大數(shù)據(jù)集或惰性計(jì)算(lazy evaluation),因?yàn)樗恍枰淮涡约虞d所有數(shù)據(jù)到內(nèi)存中。

yield 與 return 的區(qū)別:

return:一 旦執(zhí)行了 return 語句,函數(shù)就會(huì)結(jié)束,并且所有的局部變量都會(huì)被銷毀。
yield: 每當(dāng)執(zhí)行到 yield 語句時(shí),函數(shù)會(huì)暫停并返回一個(gè)值給調(diào)用者,但是函數(shù)的狀態(tài)會(huì)被保存下來,下次調(diào)用時(shí)可以從上次暫停的地方繼續(xù)執(zhí)行。

def generator(n):for i in range(n):print("before yield")yield iprint("after yield")gen = generator(3)print(next(gen))  # 第一次調(diào)用next
print("---")# 使用for循環(huán)遍歷剩余的元素 自動(dòng)調(diào)用__next__
# 第二、第三次都是在這個(gè)下面調(diào)用并打印
for i in gen:     print(i)

完整輸出結(jié)果:

before yield
0
---
after yield
before yield
1
after yield
before yield
2
after yield
(2.2) 生成器表達(dá)式

生成器表達(dá)式提供了一種簡(jiǎn)潔的方式來創(chuàng)建生成器,類似于列表推導(dǎo)式的語法,但使用圓括號(hào) () 而不是方括號(hào) [] 。與列表推導(dǎo)式不同的是,生成器表達(dá)式不會(huì)一次性生成所有元素并存儲(chǔ)在內(nèi)存中,而是按需生成每個(gè)元素。

gen_exp = (x*x for x in range(5))
print(next(gen_exp))  # 輸出: 0
print(next(gen_exp))  # 輸出: 1
print(next(gen_exp))  # 輸出: 4
# 繼續(xù)打印剩余的平方數(shù)...
4. 裝飾器

Python 裝飾器(Decorator)是一種用于修改函數(shù)或方法行為的高級(jí)特性。它本質(zhì)上是一個(gè)返回函數(shù)的函數(shù),通常用于在不改變?cè)瘮?shù)定義的情況下,為函數(shù)添加新的功能。裝飾器廣泛應(yīng)用于日志記錄、訪問控制、性能測(cè)量等場(chǎng)景。

4.1 基本概念

裝飾器的基本語法是使用 @decorator_name 語法語法糖(Syntactic Sugar)將裝飾器應(yīng)用到一個(gè)函數(shù)或方法上。例如:

@my_decorator
def my_function():print("執(zhí)行函數(shù)")

這相當(dāng)于下面的代碼:

def my_function():print("執(zhí)行函數(shù)")
my_function = my_decorator(my_function)

簡(jiǎn)單示例

以下是一個(gè)簡(jiǎn)單的裝飾器示例,該裝飾器會(huì)在調(diào)用函數(shù)前后打印消息:

def simple_decorator(func):def wrapper():print("函數(shù)之前的操作")func()print("函數(shù)之后的操作")return wrapper@simple_decorator
def say_hello():print("Hello!")say_hello()

輸出結(jié)果將是:

函數(shù)之前的操作
Hello!
函數(shù)之后的操作
4.2 帶參數(shù)的裝飾器

如果需要裝飾的函數(shù)帶有參數(shù),可以通過在 wrapper 函數(shù)中使用 *args**kwargs 來處理任意數(shù)量的位置參數(shù)和關(guān)鍵字參數(shù):

def decorator_with_arguments(func):def wrapper(*args, **kwargs):print("函數(shù)之前的操作")result = func(*args, **kwargs)print("函數(shù)之后的操作")return resultreturn wrapper@decorator_with_arguments
def greet(name):print(f"Hello, {name}!")greet("Alice")

輸出結(jié)果將是:

函數(shù)之前的操作
Hello, Alice!
函數(shù)之后的操作
4.3 帶參數(shù)的裝飾器工廠

有時(shí)你可能希望裝飾器本身也接受參數(shù)。這時(shí)可以創(chuàng)建一個(gè)裝飾器工廠,即一個(gè)返回裝飾器的函數(shù):

def repeat(num_times):def decorator_repeat(func):def wrapper(*args, **kwargs):for _ in range(num_times):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator_repeat@repeat(3)
def say_hello():print("Hello!")say_hello()

這段代碼會(huì)讓 say_hello 函數(shù)執(zhí)行三次。

4.4 類裝飾器

除了函數(shù)裝飾器外,還可以使用類作為裝飾器。為此,你需要實(shí)現(xiàn) __call__() 方法,使得類實(shí)例可調(diào)用:

class ClassDecorator:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):print("函數(shù)之前的操作")result = self.func(*args, **kwargs)print("函數(shù)之后的操作")return result@ClassDecorator
def say_goodbye():print("Goodbye!")say_goodbye()
5. 深拷貝和淺拷貝
5.1 淺拷貝(Shallow Copy

淺拷貝創(chuàng)建一個(gè)新的對(duì)象,但不遞歸地復(fù)制嵌套的對(duì)象。換句話說,原對(duì)象和新對(duì)象共享嵌套對(duì)象的引用。

特點(diǎn)

  • 創(chuàng)建一個(gè)新對(duì)象。
  • 新對(duì)象包含對(duì)原始對(duì)象中元素的引用,而不是這些元素的副本。
  • 如果原始對(duì)象中的元素是可變對(duì)象(如列表、字典),則新舊對(duì)象共享這些可變對(duì)象
import copyoriginal_list = [[1, 2], [3, 4]]
shallow_copied_list = copy.copy(original_list)# 修改淺拷貝中的一個(gè)子列表
shallow_copied_list[0][0] = 'X'print("Original List:", original_list)        # 輸出: Original List: [['X', 2], [3, 4]]
print("Shallow Copied List:", shallow_copied_list)  # 輸出: Shallow Copied List: [['X', 2], [3, 4]]

可以看到,修改淺拷貝中的子列表也影響了原始列表,因?yàn)?strong>它們共享相同的子列表對(duì)象。

5.2 深拷貝(Deep Copy

深拷貝不僅創(chuàng)建一個(gè)新的對(duì)象,還會(huì)遞歸地復(fù)制所有嵌套的對(duì)象。這意味著新對(duì)象和原始對(duì)象完全獨(dú)立,沒有任何共享的引用。

特點(diǎn)

  • 創(chuàng)建一個(gè)新對(duì)象。
  • 新對(duì)象包含原始對(duì)象中所有元素的副本,包括嵌套對(duì)象的所有層級(jí)。
  • 原始對(duì)象和新對(duì)象之間沒有共享的引用
import copyoriginal_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_list)# 修改深拷貝中的一個(gè)子列表
deep_copied_list[0][0] = 'X'print("Original List:", original_list)        # 輸出: Original List: [[1, 2], [3, 4]]
print("Deep Copied List:", deep_copied_list)  # 輸出: Deep Copied List: [['X', 2], [3, 4]]
6 lambda函數(shù)

lambda 函數(shù)的基本語法如下:

lambda 參數(shù)1, 參數(shù)2, ... : 表達(dá)式
  • 參數(shù):可以有多個(gè)參數(shù),用逗號(hào)分隔。
  • 表達(dá)式: 是一個(gè)單一的表達(dá)式,而不是一個(gè)代碼塊。lambda 函數(shù)會(huì)返回該表達(dá)式的值。
  • 快速理解 lambda 函數(shù)的一個(gè)有效方法是明確其輸入(參數(shù))輸出(表達(dá)式的結(jié)果)。你可以將 lambda 函數(shù)視為一個(gè)簡(jiǎn)單的函數(shù)定義,并且只關(guān)注它的輸入和輸出。

示例

6.1 無參數(shù)的 lambda 函數(shù):
f = lambda: "Hello, World!"
print(f())  # 輸出: Hello, World!
6.2 帶參數(shù)的 lambda 函數(shù):
add = lambda x, y: x + y
print(add(5, 3))  # 輸出: 8
6.3 帶有默認(rèn)參數(shù)的 lambda 函數(shù):
power = lambda x, n=2: x ** n
print(power(2))      # 輸出: 4 (2^2)
print(power(2, 3))   # 輸出: 8 (2^3)
6.4 使用條件表達(dá)式的 lambda 函數(shù):
max_value = lambda a, b: a if a > b else b
print(max_value(10, 20))  # 輸出: 20

使用場(chǎng)景
lambda 函數(shù)最常用于需要將一個(gè)小函數(shù)作為參數(shù)傳遞給其他函數(shù)的場(chǎng)合,比如高階函數(shù)(如 map(), filter(), sorted() 等)。

1. map() 函數(shù)
map() 函數(shù)可以對(duì)可迭代對(duì)象中的每個(gè)元素應(yīng)用一個(gè)函數(shù),并返回一個(gè)新的迭代器。

numbers = [1, 2, 3, 4]
squared_numbers = map(lambda x: x ** 2, numbers)
print(list(squared_numbers))  # 輸出: [1, 4, 9, 16]

2. filter() 函數(shù)
filter() 函數(shù)可以根據(jù)指定條件過濾可迭代對(duì)象中的元素。

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 輸出: [2, 4, 6]

3. sorted() 函數(shù)

sorted() 函數(shù)可以根據(jù)指定的關(guān)鍵字對(duì)可迭代對(duì)象進(jìn)行排序。

students = [{"name": "Alice", "age": 25},{"name": "Bob", "age": 20},{"name": "Charlie", "age": 22}
]sorted_students = sorted(students, key=lambda student: student["age"])
print(sorted_students)
# 輸出: [{'name': 'Bob', 'age': 20}, {'name': 'Charlie', 'age': 22}, {'name': 'Alice', 'age': 25}]

4. 在列表推導(dǎo)式中使用 lambda
雖然列表推導(dǎo)式本身已經(jīng)很簡(jiǎn)潔了,但在某些情況下結(jié)合 lambda 函數(shù)可以進(jìn)一步簡(jiǎn)化代碼。

numbers = [1, 2, 3, 4]
doubled = [(lambda x: x * 2)(n) for n in numbers]
print(doubled)  # 輸出: [2, 4, 6, 8]
7. Python垃圾回收機(jī)制

Python 的垃圾回收機(jī)制(Garbage Collection, GC)主要用于自動(dòng)管理內(nèi)存,釋放不再使用的對(duì)象所占用的內(nèi)存資源。理解 Python垃圾回收機(jī)制有助于編寫更高效的代碼,并避免內(nèi)存泄漏等問題。

7.1 引用計(jì)數(shù)(Reference Counting

這是 Python 最基本的垃圾回收機(jī)制。每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)器,記錄當(dāng)前有多少個(gè)引用指向該對(duì)象。當(dāng)引用計(jì)數(shù)變?yōu)榱銜r(shí),說明沒有其他對(duì)象在使用它,可以安全地釋放其占用的內(nèi)存。

工作原理

  • 當(dāng)一個(gè)對(duì)象被創(chuàng)建并賦值給一個(gè)變量時(shí),該對(duì)象的引用計(jì)數(shù)加一。
  • 當(dāng)有新的變量引用同一個(gè)對(duì)象時(shí),引用計(jì)數(shù)再次加一
  • 當(dāng)某個(gè)變量不再引用該對(duì)象時(shí),引用計(jì)數(shù)減一。
  • 當(dāng)引用計(jì)數(shù)降為零時(shí)Python 自動(dòng)調(diào)用該對(duì)象的 __del__ 方法(如果定義了),然后釋放其占用的內(nèi)存。
7.2 循環(huán)引用檢測(cè)(Cycle Detection

雖然引用計(jì)數(shù)機(jī)制簡(jiǎn)單高效,但它無法處理循環(huán)引用的情況。例如,兩個(gè)對(duì)象相互引用形成一個(gè)閉環(huán),即使這些對(duì)象已經(jīng)沒有任何外部引用,它們的引用計(jì)數(shù)也不會(huì)降為零,從而導(dǎo)致內(nèi)存泄漏。

為了解決這個(gè)問題,Python 使用了一個(gè)基于 標(biāo)記-清除(Mark-and-Sweep) 和 分代收集(Generational Garbage Collection) 的算法來檢測(cè)和清理循環(huán)引用。

工作原理

標(biāo)記-清除算法分為兩個(gè)主要階段:標(biāo)記階段 和 清除階段。

標(biāo)記階段:

  • 從根對(duì)象(如全局變量、活動(dòng)棧幀等)開始遍歷所有可達(dá)對(duì)象,并將這些對(duì)象標(biāo)記為活躍對(duì)象。
  • 根對(duì)象是指那些始終可以被訪問的對(duì)象,例如當(dāng)前正在使用的變量、函數(shù)調(diào)用棧中的局部變量等。

清除階段:

  • 掃描整個(gè)堆內(nèi)存,找到未被標(biāo)記的對(duì)象并將其刪除。
  • 清除階段會(huì)釋放這些對(duì)象占用的內(nèi)存,并將其返回給可用內(nèi)存池。

假設(shè)我們有以下對(duì)象圖:

A -> B
B -> C
C -> D
D -> E
E -> A (循環(huán)引用)

在這個(gè)例子中,A -> B -> C -> D -> E -> A 形成了一個(gè)循環(huán)引用。如果沒有其他外部引用指向這些對(duì)象,那么即使引用計(jì)數(shù)不會(huì)降為零,這些對(duì)象也應(yīng)該被回收。

標(biāo)記階段:

  • 從根對(duì)象開始遍歷,假設(shè)只有 A 被根對(duì)象引用。
  • 遍歷 A,發(fā)現(xiàn)它引用了 B,標(biāo)記 B。
  • 遍歷 B,發(fā)現(xiàn)它引用了 C,標(biāo)記 C。 繼續(xù)遍歷
  • CD,標(biāo)記 DE。
  • 最終,所有對(duì)象都被標(biāo)記為活躍對(duì)象。

清除階段:

  • 掃描整個(gè)堆內(nèi)存,發(fā)現(xiàn)沒有未被標(biāo)記的對(duì)象,因此不需要清除任何對(duì)象。

如果根對(duì)象不再引用 A,則在標(biāo)記階段無法到達(dá) A 及其循環(huán)引用鏈上的對(duì)象,這些對(duì)象會(huì)被標(biāo)記為不可達(dá)并在清除階段被刪除。

分代回收(Generational Garbage Collection

分代回收是一種優(yōu)化策略,基于一個(gè)觀察:大多數(shù)對(duì)象在創(chuàng)建后很快就會(huì)被銷毀,而那些存活較長(zhǎng)時(shí)間的對(duì)象不太可能被銷毀。因此,Python 將對(duì)象分為三個(gè)世代(Generation),分別是第 0 代、第 1 代和第 2 代。

工作原理

  • (1) 對(duì)象分配與提升:

    • 新創(chuàng)建的對(duì)象屬于第 0 代。
    • 當(dāng)?shù)?0 代對(duì)象經(jīng)過一次垃圾回收后仍然存活,它會(huì)被提升到第 1 代。
    • 類似地,第 1 代對(duì)象經(jīng)過垃圾回收后仍然存活,則會(huì)被提升到第 2 代。
  • (2) 垃圾回收頻率:

    • 0 代對(duì)象的垃圾回收頻率最高,因?yàn)樗鼈冏钣锌赡鼙豢焖黉N毀。
    • 1 代和第 2 代對(duì)象的垃圾回收頻率逐漸降低,因?yàn)樗鼈兏锌赡荛L(zhǎng)期存活。
  • (3) 閾值設(shè)置:

    • 每個(gè)世代都有一個(gè)閾值,表示在該世代對(duì)象數(shù)量達(dá)到一定值時(shí)觸發(fā)垃圾回收。
    • 默認(rèn)的閾值可以通過 gc.get_threshold() 獲取,并且可以通過 gc.set_threshold(gen0, gen1, gen2) 進(jìn)行設(shè)置。
8 多線程與多進(jìn)程

Python 中,多線程(Multithreading)和多進(jìn)程(Multiprocessing是兩種常見的并行編程方法,用于提高程序的性能和響應(yīng)速度。盡管它們都旨在實(shí)現(xiàn)并發(fā)執(zhí)行,但它們的工作原理和適用場(chǎng)景有所不同。

CPU密集型任務(wù): CPU 密集型任務(wù)是指那些主要依賴于 CPU 計(jì)算能力的任務(wù)。這類任務(wù)通常需要大量的計(jì)算資源,包括復(fù)雜的數(shù)學(xué)運(yùn)算、數(shù)據(jù)處理、圖像處理、視頻編碼等。
I/O 密集型任務(wù): I/O 密集型任務(wù)是指那些主要依賴于外部輸入輸出操作的任務(wù)。這類任務(wù)通常涉及大量的文件讀寫、網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫查詢等。

8.1 多進(jìn)程

基本概念

多進(jìn)程是指在一個(gè)程序中同時(shí)運(yùn)行多個(gè)進(jìn)程。每個(gè)進(jìn)程都有獨(dú)立的內(nèi)存空間和解釋器實(shí)例, 因此它們可以真正并行執(zhí)行任務(wù),不受 GIL 的限制。

工作原理

8.1.1進(jìn)程間通信(IPC):

  • 進(jìn)程之間不能直接共享內(nèi)存,必須通過特定的機(jī)制進(jìn)行通信,如QueuePipeManager 對(duì)象。
  • multiprocessing.Queue 提供了一個(gè)線程和進(jìn)程安全的隊(duì)列,用于在不同進(jìn)程之間傳遞數(shù)據(jù)。
  • multiprocessing.Pipe 提供了雙向通信通道,適用于父子進(jìn)程之間的通信。

8.1.2 創(chuàng)建和管理進(jìn)程:

  • 使用 multiprocessing.Process 類來創(chuàng)建和管理進(jìn)程。
  • 進(jìn)程可以通過調(diào)用 start() 方法開始執(zhí)行,并通過 join() 方法等待進(jìn)程完成。

示例代碼

python
深色版本
import multiprocessing
import timedef print_numbers(queue):for i in range(5):queue.put(f"數(shù)字: {i}")time.sleep(1)def print_letters(queue):for letter in 'ABCDE':queue.put(f"字母: {letter}")time.sleep(1)if __name__ == "__main__":# 創(chuàng)建一個(gè)隊(duì)列用于進(jìn)程間通信queue = multiprocessing.Queue()# 創(chuàng)建進(jìn)程p1 = multiprocessing.Process(target=print_numbers, args=(queue,))p2 = multiprocessing.Process(target=print_letters, args=(queue,))# 啟動(dòng)進(jìn)程p1.start()p2.start()# 從隊(duì)列中讀取數(shù)據(jù)并打印while True:if not queue.empty():print(queue.get())if not p1.is_alive() and not p2.is_alive():break# 等待兩個(gè)進(jìn)程完成p1.join()p2.join()
8.2 多線程(Multithreading

基本概念

多線程是指在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)線程。每個(gè)線程都是一個(gè)獨(dú)立的執(zhí)行路徑,可以并發(fā)執(zhí)行不同的任務(wù)。Pythonthreading 模塊提供了對(duì)多線程的支持。

工作原理

(1)GIL(Global Interpreter Lock)

  • CPython 解釋器使用 GIL 來確保同一時(shí)刻只有一個(gè)線程在執(zhí)行 Python 字節(jié)碼(Python 源代碼被編譯成字節(jié)碼,這是一種低級(jí)的中間表示形式,由 Python 虛擬機(jī)解釋執(zhí)行)。這意味著即使有多個(gè)線程,它們也不能真正并行執(zhí)行CPU 密集型任務(wù)。
  • 但是,對(duì)于 I/O 密集型任務(wù)(如文件讀寫、網(wǎng)絡(luò)請(qǐng)求等),多線程仍然可以提高效率,因?yàn)檫@些任務(wù)在等待 I/O操作時(shí)會(huì)釋放 GIL,允許其他線程繼續(xù)執(zhí)行。

(2)創(chuàng)建和管理線程:

  • 使用 threading.Thread 類來創(chuàng)建和管理線程。
  • 線程可以通過調(diào)用 start() 方法開始執(zhí)行,并通過 join() 方法等待線程完成。

知識(shí)擴(kuò)展

GIL 的作用

  • 簡(jiǎn)化內(nèi)存管理: GIL 簡(jiǎn)化了 Python 內(nèi)存管理的設(shè)計(jì),使得解釋器不需要處理復(fù)雜的線程同步問題。
  • 保護(hù)內(nèi)置數(shù)據(jù)結(jié)構(gòu): 許多 Python 內(nèi)置的數(shù)據(jù)結(jié)構(gòu)和庫并不是線程安全的,GIL 提供了一種簡(jiǎn)單的保護(hù)機(jī)制,防止多個(gè)線程同時(shí)修改這些數(shù)據(jù)結(jié)構(gòu)。

為什么說 Python 的多線程是“假的”

  • 無法實(shí)現(xiàn)真正的并行計(jì)算:由于 GIL 的存在,多線程不能真正并行執(zhí)行 CPU 密集型任務(wù)。即使在多核 CPU 上,也只能有一個(gè)線程在執(zhí)行Python 字節(jié)碼,這與我們通常理解的多線程并行計(jì)算相悖。
  • 增加了上下文切換的開銷:在某些情況下,特別是當(dāng)線程頻繁切換時(shí),上下文切換的開銷可能會(huì)導(dǎo)致性能下降,甚至比單線程執(zhí)行還要慢。
  • 誤導(dǎo)性:初學(xué)者可能會(huì)誤以為使用多線程可以顯著提升程序的性能,尤其是在 CPU 密集型任務(wù)中,但實(shí)際上效果并不明顯,甚至可能適得其反。

示例代碼

import threading
import timedef print_numbers():for i in range(5):print(f"數(shù)字: {i}")time.sleep(1)def print_letters():for letter in 'ABCDE':print(f"字母: {letter}")time.sleep(1)# 創(chuàng)建線程
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)# 啟動(dòng)線程
t1.start()
t2.start()# 等待兩個(gè)線程完成
t1.join()
t2.join()
http://m.aloenet.com.cn/news/36411.html

相關(guān)文章:

  • 北京自助模板建站黑馬程序員培訓(xùn)機(jī)構(gòu)在哪
  • 學(xué)生做的網(wǎng)站成品網(wǎng)絡(luò)客服
  • 西安微網(wǎng)站制作網(wǎng)上廣告宣傳怎么做
  • 畢業(yè)設(shè)計(jì)網(wǎng)站成品百度接單平臺(tái)
  • 做B2C獨(dú)立網(wǎng)站的話需要做海外倉(cāng)嗎人際網(wǎng)絡(luò)營(yíng)銷2900
  • 高端電子網(wǎng)站建設(shè)谷歌官方seo入門指南
  • 子目錄 獨(dú)立的網(wǎng)站網(wǎng)上怎么發(fā)布廣告
  • 網(wǎng)站源碼破解版網(wǎng)站關(guān)鍵詞優(yōu)化排名外包
  • 金融投資公司網(wǎng)站模板網(wǎng)站工具查詢
  • 江蘇省城鄉(xiāng)建設(shè)官網(wǎng)站免費(fèi)私人網(wǎng)站建設(shè)
  • wordpress文章全部刪除優(yōu)化seo深圳
  • 不建網(wǎng)站如何做淘寶客社交網(wǎng)絡(luò)推廣方法
  • 江陰外貿(mào)網(wǎng)站制作福州網(wǎng)站建設(shè)
  • 修改網(wǎng)站圖標(biāo)卡一卡二卡三入口2021
  • 浙里建官方網(wǎng)站百度指數(shù)的主要功能有
  • 手機(jī)端網(wǎng)站開發(fā)長(zhǎng)沙網(wǎng)站seo方法
  • 美食網(wǎng)站的設(shè)計(jì)與制作友情鏈接方面pr的選擇應(yīng)該優(yōu)先選擇的鏈接為
  • 怎樣做原創(chuàng)短視頻網(wǎng)站百度關(guān)鍵詞工具
  • 網(wǎng)站建設(shè)網(wǎng)站推廣公司怎么建立自己的網(wǎng)站
  • 百度關(guān)鍵詞怎么做排名愛站工具seo綜合查詢
  • 公眾微信綁定網(wǎng)站帳號(hào)安卓aso優(yōu)化排名
  • 國(guó)外的工業(yè)設(shè)計(jì)網(wǎng)站seo就業(yè)前景如何
  • html5網(wǎng)站動(dòng)效怎么做百度一下官網(wǎng)首頁百度一下百度
  • 什么做網(wǎng)站推廣百度售后服務(wù)電話
  • 鄒城網(wǎng)站建設(shè)搜索引擎營(yíng)銷的英文簡(jiǎn)稱
  • 銷售類電商網(wǎng)站如何做優(yōu)化友情鏈接聯(lián)盟
  • 重慶市建設(shè)工程信息網(wǎng)的信用信息發(fā)布平臺(tái)廈門seo網(wǎng)絡(luò)推廣
  • 基于目的地的o2o旅游電子商務(wù)網(wǎng)站開發(fā)設(shè)計(jì)畢業(yè)設(shè)計(jì)公眾號(hào)推廣平臺(tái)
  • 防城港做網(wǎng)站的培訓(xùn)機(jī)構(gòu)有哪些
  • 深圳做微信網(wǎng)站建設(shè)公司網(wǎng)站制作費(fèi)用