偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

編寫(xiě)優(yōu)雅代碼的八個(gè)內(nèi)置Python裝飾器

譯文
開(kāi)發(fā)
開(kāi)發(fā)人員可以使用裝飾器來(lái)修改函數(shù)的行為,而無(wú)需更改源代碼。這提供了一種簡(jiǎn)潔而靈活的方式以增強(qiáng)和擴(kuò)展函數(shù)的功能。

譯者 | 布加迪

審校 | 重樓

Python具有語(yǔ)法清晰易讀的優(yōu)點(diǎn),是一種廣泛使用的高級(jí)編程語(yǔ)言。Python是為確保易用性而設(shè)計(jì)的,注重簡(jiǎn)性和降低程序維護(hù)成本。它隨帶一個(gè)廣泛的庫(kù),減少了開(kāi)發(fā)人員從頭開(kāi)始編寫(xiě)代碼的需要,并提高了開(kāi)發(fā)人員的生產(chǎn)力。Python的一項(xiàng)有助于確保代碼優(yōu)雅的強(qiáng)大特性是裝飾器(decorator)。

Python裝飾器的定義

Python中,decorator是一個(gè)函數(shù),允許您修改另一個(gè)函數(shù)的行為,而不改變其核心邏輯。它接受另一個(gè)函數(shù)作為參數(shù),并返回功能得到擴(kuò)展的函數(shù)。這樣一來(lái),您可以使用裝飾器現(xiàn)有函數(shù)添加一些額外的邏輯,只需要幾行代碼就可以提高可重用性。我們在本文中將介紹8個(gè)內(nèi)置的Python裝飾器,它們可以幫助您編寫(xiě)更優(yōu)雅、更易于維護(hù)的代碼。

1. @atexit.register

@atexit.register裝飾器用于注冊(cè)在程序結(jié)束時(shí)執(zhí)行的函數(shù)。函數(shù)可用于在程序即將退出時(shí)執(zhí)行任何任務(wù),無(wú)論是由于正常執(zhí)行還是由于意外錯(cuò)誤。

例子

import atexit

# Register the exit_handler function
@atexit.register
def exit_handler():
 print("Exiting the program. Cleanup tasks can be performed here.")

# Rest of the program
def main():
 print("Inside the main function.")
 # Your program logic goes here.

if __name__ == "__main__":
 main()

輸出

Inside the main function.
Exiting the program. Cleanup tasks can be performed here.

上面的實(shí)現(xiàn)中,@atexit.register在函數(shù)定義上面提及。它將exit_handler()函數(shù)定義為退出函數(shù)。實(shí)際上,這意味著每當(dāng)程序到達(dá)其終止點(diǎn),無(wú)論是通過(guò)正常執(zhí)行還是由于意外錯(cuò)誤導(dǎo)致過(guò)早退出,都將調(diào)用exit_handler()函數(shù)。

2. @dataclasses.dataclass

@dataclasses.dataclass是一個(gè)功能強(qiáng)大的裝飾器,用于自動(dòng)為__init____repr__其他類(lèi)生成常見(jiàn)的特殊方法。由于不需要編寫(xiě)用于初始化和比較類(lèi)實(shí)例樣板方法,它可以幫助您編寫(xiě)更干凈、更簡(jiǎn)潔的代碼。它還可以通過(guò)確保在整個(gè)代碼庫(kù)中一致地實(shí)現(xiàn)常見(jiàn)的特殊方法來(lái)幫助防止錯(cuò)誤。

例子:

from dataclasses import dataclass

@dataclass
class Point:
 x: int
 y: int


point = Point(x=3, y=2)
# Printing object
print(point)

# Checking for the equality of two objects
point1 = Point(x=1, y=2)
point2 = Point(x=1, y=2)
print(point1 == point2)

輸出:
Point(x=3, y=2)
True

@dataclass裝飾器應(yīng)用于Point類(lèi)定義之上,通知Python使用默認(rèn)行為來(lái)生成特殊方法。這會(huì)自動(dòng)創(chuàng)建__init__方法,該方法在對(duì)象實(shí)例化時(shí)初始化類(lèi)屬性,比如x和y。因此,可以在不需要顯式編碼的情況下構(gòu)造像point這樣的實(shí)例。此外,負(fù)責(zé)提供對(duì)象字符串表示的__repr__方法也會(huì)自動(dòng)加以調(diào)整。這確保了在打印輸出對(duì)象(比如point)時(shí),它會(huì)生成清晰有序的表示,比如輸出point (x=3, y=2)中所示。

此外,兩個(gè)實(shí)例point1和point2之間的相等性比較(==)生成True。這值得注意,因?yàn)槟J(rèn)情況下,Python根據(jù)內(nèi)存位置來(lái)檢查是否相等。然而,在數(shù)據(jù)類(lèi)對(duì)象上下文中,相等性取決于其中含的數(shù)據(jù)。這是由于@dataclass裝飾器生成了一個(gè)__eq__方法,該方法檢查對(duì)象中存在的數(shù)據(jù)是否相等,而不是檢查相同的內(nèi)存位置。

3. @enum.unique

@enum.unique裝飾器位于enum模塊中,用于確保枚舉中所有成員的值是唯一的。這有助于防止意外創(chuàng)建具有相同值的多個(gè)枚舉成員,不然會(huì)導(dǎo)致混淆和錯(cuò)誤。如果發(fā)現(xiàn)重復(fù)的值,拋出ValueError(值錯(cuò)誤)。

例子

from enum import Enum, unique

@unique
class VehicleType(Enum):
 CAR = 1
 TRUCK = 2
 MOTORCYCLE = 3
 BUS = 4

# Attempting to create an enumeration with a duplicate value will raise a ValueError
try:
 @unique
 class DuplicateVehicleType(Enum):
 CAR = 1
 TRUCK = 2
 MOTORCYCLE = 3
 # BUS and MOTORCYCLE have duplicate values
 BUS = 3
except ValueError as e:
 print(f"Error: {e}")

輸出

Error: duplicate values found in : BUS -> MOTORCYCLE

在上述實(shí)現(xiàn)中,BUSMOTORCYCLE有相同的值3。因此,@unique裝飾器拋出值錯(cuò)誤,顯示一條消息,表明發(fā)現(xiàn)了重復(fù)的值。既不能多次使用相同的鍵,也不能將相同的值分配給不同的成員。通過(guò)這種方式,它有助于防止多個(gè)枚舉成員出現(xiàn)重復(fù)值。

4. @partial

partial裝飾器是一個(gè)強(qiáng)大的工具,用于創(chuàng)建偏函數(shù)。偏函數(shù)允許預(yù)先設(shè)置一些原始函數(shù)的參數(shù),然后用已經(jīng)填寫(xiě)的這些參數(shù)生成一個(gè)新的函數(shù)。

例子:

from functools import partial

# Original function
def power(base, exponent):
 return base ** exponent

# Creating a partial function with the exponent fixed to 2
square = partial(power, expnotallow=2)

# Using the partial function
result = square(3)
print("Output:",result)

輸出

Output: 9

上面的實(shí)現(xiàn)中,我們有一個(gè)函數(shù)power,它接受兩個(gè)參數(shù)baseexponent,并返回指數(shù)次冪基數(shù)的結(jié)果。我們使用原始函數(shù)創(chuàng)建了一個(gè)名為square偏函數(shù),其中指數(shù)被預(yù)先設(shè)置為2。這樣一來(lái),我們可以使用partial裝飾器擴(kuò)展原始函數(shù)的功能。

5. @singledispatch

@singledisptach裝飾器用于創(chuàng)建泛型函數(shù)。它允許您定義名稱(chēng)相同但參數(shù)類(lèi)型各異的函數(shù)的不同實(shí)現(xiàn)。當(dāng)您希望代碼針對(duì)不同的數(shù)據(jù)類(lèi)型有不同的行為時(shí),這個(gè)裝飾器就特別有用。

例子

from functools import singledispatch

# Decorator
@singledispatch
def display_info(arg):
 print(f"Generic: {arg}")

# Registering specialized implementations for different types
@display_info.register(int)
def display_int(arg):
 print(f"Received an integer: {arg}")

@display_info.register(float)
def display_float(arg):
 print(f"Received a float: {arg}")

@display_info.register(str)
def display_str(arg):
 print(f"Received a string: {arg}")

@display_info.register(list)
def display_sequence(arg):
 print(f"Received a sequence: {arg}")

# Using the generic function with different types
display_info(39) 
display_info(3.19) 
display_info("Hello World!")
display_info([2, 4, 6]) 

輸出

Received an integer: 39
Received a float: 3.19
Received a string: Hello World!
Received a sequence: [2, 4, 6]

在上面的實(shí)現(xiàn)中,我們先使用@singledisptach裝飾器開(kāi)發(fā)了泛型函數(shù)display_info(),然后分別為整數(shù)、浮點(diǎn)字符串和列表注冊(cè)了實(shí)現(xiàn)。輸出顯示了display_info()針對(duì)不同數(shù)據(jù)類(lèi)型的工作機(jī)理。

6. @classmethod

@classmethod是一個(gè)裝飾器,用于在類(lèi)中定義類(lèi)方法。類(lèi)方法綁定到類(lèi)而不是綁定到類(lèi)的對(duì)象。靜態(tài)方法類(lèi)方法的主要區(qū)別在于它們與類(lèi)狀態(tài)的交互。類(lèi)方法可以訪(fǎng)問(wèn)并修改類(lèi)狀態(tài),而靜態(tài)方法無(wú)法訪(fǎng)問(wèn)類(lèi)狀態(tài)獨(dú)立操作。

例子

class Student:
 total_students = 0

 def __init__(self, name, age):
 self.name = name
 self.age = age
 Student.total_students += 1

 @classmethod
 def increment_total_students(cls):
 cls.total_students += 1
 print(f"Class method called. Total students now: {cls.total_students}")

# Creating instances of the class
student1 = Student(name="Tom", age=20)
student2 = Student(name="Cruise", age=22)

# Calling the class method
Student.increment_total_students() #Total students now: 3

# Accessing the class variable
print(f"Total students from student 1: {student1.total_students}")
print(f"Total students from student 2: {student2.total_students}")

輸出

Class method called. Total students now: 3
Total students from student 1: 3
Total students from student 2: 3

在上面的實(shí)現(xiàn)中,Student類(lèi)擁有total_students這個(gè)類(lèi)變量。@classmethod裝飾器用于定義increment_total_students()類(lèi)方法,以增加total_students變量。每當(dāng)我們創(chuàng)建Student類(lèi)的實(shí)例時(shí),學(xué)生總數(shù)就增加1。我們創(chuàng)建了這個(gè)類(lèi)的兩個(gè)實(shí)例,然后使用類(lèi)方法將total_students變量修改為3,這個(gè)類(lèi)的實(shí)例也反映了這點(diǎn)。

7. @staticmethod

@staticmethod裝飾器用于在類(lèi)中定義靜態(tài)方法。靜態(tài)方法是無(wú)需創(chuàng)建類(lèi)實(shí)例即可調(diào)用的方法。靜態(tài)方法常常用于不需要訪(fǎng)問(wèn)與對(duì)象相關(guān)的參數(shù),整個(gè)類(lèi)更相關(guān)。

例子

class MathOperations:
 @staticmethod
 def add(x, y):
 return x + y

 @staticmethod
 def subtract(x, y):
 return x - y

# Using the static methods without creating an instance of the class
sum_result = MathOperations.add(5, 4)
difference_result = MathOperations.subtract(8, 3)

print("Sum:", sum_result) 
print("Difference:", difference_result)

輸出

Sum: 9
Difference: 5

在上面的實(shí)現(xiàn)中,我們使用@staticmethod為類(lèi)MathOperations定義了一個(gè)靜態(tài)方法add()。我們添加了兩個(gè)數(shù)字45,結(jié)果是9,沒(méi)有創(chuàng)建類(lèi)的任何實(shí)例。同樣,將83兩個(gè)數(shù)字相減得到5。這樣一來(lái),就可以生成靜態(tài)方法,以執(zhí)行不需要實(shí)例狀態(tài)的效用函數(shù)。

8. @ property

@property裝飾器用于定義類(lèi)屬性的getter方法。getter方法是返回屬性值的方法。這方法用于數(shù)據(jù)封裝,指定誰(shuí)可以訪(fǎng)問(wèn)類(lèi)或?qū)嵗脑敿?xì)信息。

例子

class Circle:
 def __init__(self, radius):
 self._radius = radius

 @property
 def radius(self):
 # Getter method for the radius.
 return self._radius

 @property
 def area(self):
 # Getter method for the area.
 return 3.14 * self._radius**2

# Creating an instance of the Circle class
my_circle = Circle(radius=5)

# Accessing properties using the @property decorator
print("Radius:", my_circle.radius) 
print("Area:", my_circle.area) 

輸出

Radius: 5
Area: 78.5

在上面的實(shí)現(xiàn)中,類(lèi)Circle有一個(gè)屬性radius。我們使用@property為半徑和面積設(shè)置getter方法。它為類(lèi)的用戶(hù)提供了一個(gè)干凈一致的接口來(lái)訪(fǎng)問(wèn)這些屬性。

結(jié)語(yǔ)

本文重點(diǎn)介紹了一些最通用和最實(shí)用的裝飾器,您可以使用它們提高代碼靈活性和可讀。這些修飾器可以擴(kuò)展原始函數(shù)的功能,使原始函數(shù)富條理性,更不容易出錯(cuò)。它們如同神奇的魔法棒,使的Python程序看起來(lái)整潔、運(yùn)行起來(lái)順暢。

原文標(biāo)題:8 Built-in Python Decorators to Write Elegant Code,作者:Kanwal Mehreen

鏈接:https://www.kdnuggets.com/8-built-in-python-decorators-to-write-elegant-code


責(zé)任編輯:華軒 來(lái)源: 51CTO
相關(guān)推薦

2024-09-12 15:32:35

裝飾器Python

2022-06-17 09:08:27

代碼Python內(nèi)置庫(kù)

2024-09-23 09:00:00

裝飾器函數(shù)代碼

2022-09-21 13:32:39

Python裝飾器

2024-05-21 10:40:09

開(kāi)發(fā)前端裝飾器

2022-07-25 15:21:50

Java編程語(yǔ)言開(kāi)發(fā)

2025-01-06 12:00:00

Python函數(shù)內(nèi)置函數(shù)

2016-09-19 15:15:01

shellbash腳本

2022-03-18 21:27:36

Python無(wú)代碼

2025-02-17 08:50:00

CSS代碼JavaScript

2023-09-26 12:04:15

重構(gòu)技巧Pythonic

2023-01-11 11:35:40

重構(gòu)PythonPythonic

2024-03-27 14:06:58

Python代碼開(kāi)發(fā)

2010-11-09 14:18:41

2009-12-03 17:18:19

軟件路由器功能

2023-02-06 12:00:00

重構(gòu)PythonPythonic

2017-01-05 09:59:45

2012-10-29 11:01:17

2017-04-20 12:51:28

2024-11-11 06:10:00

Python生成器迭代器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)