1.類(Class)
在Python中類(Class)是面向對象編程(OOP)的核心概念。
1.1.類的基本定義
- 最簡單的類
class Cat:"""這是一個最簡單的類"""pass
#創建實例
obj = Cat()
- 包含方法的類
class Cat:"""這是一個最簡單的類"""def bark(self):return "miao"def eat(self, food):return f"吃{food}"
#創建實例
obj = Cat()
1.2.構造方法__init__()
class Person:def __init__(self, name, age):"""構造方法,初始化示例屬性"""self.name = nameself.age = ageself.is_adult = age >= 18def introduce(self):return f"我叫{self.name}, 今年{self.age}歲"#創建實例
person = Person("張三", 25)
print(person.introduce())
1.3.類屬性和實例屬性
class Car:#類屬性wheels = 4country = "中國"def __init__(self, brand, color):#實例屬性self.brand = brandself.color = colordef info(self):return f"{self.color}的{self.brand},有{self.wheels}個輪子"car = Car("豐田", "黑色")
print(car.info())
1.4.繼承
類的繼承可以包括單集成多集成,類定義后面括弧里面添加集成的父類
- 單繼承
class Animal:def __init__(self, name):self.name = namedef speak(self):return "動物叫"class Dog(Animal):def __init__(self, name, breed):super().__init__(name)self.breed = breeddef speak(self):return "旺旺"def fetch(self):return f"{self.name}在接飛盤"#使用
dog = Dog("小黑", "拉布拉多")
print(dog.speak())
print(dog.fetch())
print(dog.name)
- 多繼承
class Flyable:def fly(self):return "我能飛"class Swimmable:def swim(self):return "我能游泳"class Duck(Flyable, Swimmable): # 多繼承def __init__(self, name):self.name = namedef quack(self):return "嘎嘎!"# 使用
duck = Duck("唐老鴨")
print(duck.quack()) # 輸出: 嘎嘎!
print(duck.fly()) # 輸出: 我能飛
print(duck.swim()) # 輸出: 我能游泳
1.5.封裝-訪問控制
使用命名約定
class BankAccount:def __init__(self, owner, balance=0):self.owner = owner # 公開屬性self._balance = balance # 受保護屬性(約定)self.__password = "123456" # 私有屬性(名稱修飾)def deposit(self, amount):"""存款"""if amount > 0:self._balance += amountreturn Truereturn Falsedef withdraw(self, amount):"""取款"""if 0 < amount <= self._balance:self._balance -= amountreturn Truereturn Falsedef get_balance(self):"""獲取余額(公開方法)"""return self._balancedef _internal_method(self):"""受保護方法"""return "內部方法"def __private_method(self):"""私有方法"""return "私有方法"# 使用
account = BankAccount("張三", 1000)
print(account.owner) # 輸出: 張三
print(account.get_balance()) # 輸出: 1000# 仍然可以訪問(但不應該)
print(account._balance) # 輸出: 1000
# print(account.__password) # 錯誤:AttributeError
1.6類方法和靜態方法
class MathUtils:# 類屬性PI = 3.14159@classmethoddef circle_area(cls, radius):"""類方法:計算圓面積"""return cls.PI * radius ** 2@staticmethoddef add(a, b):"""靜態方法:加法"""return a + bdef instance_method(self):"""實例方法"""return "實例方法"# 使用
print(MathUtils.circle_area(5)) # 輸出: 78.53975
print(MathUtils.add(3, 4)) # 輸出: 7# 也可以通過實例調用
utils = MathUtils()
print(utils.circle_area(3)) # 輸出: 28.27431
1.7使用示例
class Student:def __init__(self, name, student_id):self.name = nameself.student_id = student_idself.courses = {} # 課程字典 {課程名: 成績}self.gpa = 0.0def enroll_course(self, course_name):"""選課"""if course_name not in self.courses:self.courses[course_name] = Nonereturn Truereturn Falsedef update_grade(self, course_name, grade):"""更新成績"""if course_name in self.courses and 0 <= grade <= 100:self.courses[course_name] = gradeself._calculate_gpa()return Truereturn Falsedef _calculate_gpa(self):"""計算GPA(私有方法)"""valid_grades = [g for g in self.courses.values() if g is not None]if valid_grades:self.gpa = sum(valid_grades) / len(valid_grades)def get_info(self):"""獲取學生信息"""return {'name': self.name,'student_id': self.student_id,'courses': self.courses.copy(),'gpa': self.gpa}def __str__(self):return f"學生{self.name}(學號:{self.student_id})"class StudentManager:def __init__(self):self.students = {}def add_student(self, name, student_id):"""添加學生"""if student_id not in self.students:self.students[student_id] = Student(name, student_id)return Truereturn Falsedef get_student(self, student_id):"""獲取學生"""return self.students.get(student_id)def remove_student(self, student_id):"""刪除學生"""if student_id in self.students:del self.students[student_id]return Truereturn False# 使用示例
manager = StudentManager()
manager.add_student("張三", "2023001")
manager.add_student("李四", "2023002")student = manager.get_student("2023001")
student.enroll_course("數學")
student.enroll_course("英語")
student.update_grade("數學", 85)
student.update_grade("英語", 92)print(student.get_info())
1.8抽象基類
from abc import ABC, abstractmethodclass Shape(ABC): # 抽象基類@abstractmethoddef area(self):"""計算面積"""pass@abstractmethoddef perimeter(self):"""計算周長"""passclass Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = heightdef area(self):return self.width * self.heightdef perimeter(self):return 2 * (self.width + self.height)# 使用
rect = Rectangle(5, 3)
print(f"面積: {rect.area()}") # 輸出: 面積: 15
print(f"周長: {rect.perimeter()}") # 輸出: 周長: 16# shape = Shape() # 錯誤:不能實例化抽象類
2.方法(Method)
2.1.方法類型
方法的類型分為示例方法、類方法、靜態方法
- 實例方法
class Calculator:def add(self, a, b): # self是必須的第一個參數"""實例方法:加法"""return a + bdef multiply(self, a, b):"""實例方法:乘法"""return a * b# 使用
calc = Calculator()
result = calc.add(5, 3) # 輸出: 8
print(result)
通過使用注解@classmethod
- 類方法
class MathUtils:PI = 3.14159@classmethoddef circle_area(cls, radius): # cls代表類本身"""類方法:計算圓面積"""return cls.PI * radius ** 2@classmethoddef set_pi(cls, new_pi):"""修改類屬性"""cls.PI = new_pi# 使用
print(MathUtils.circle_area(5)) # 通過類調用: 78.53975
print(MathUtils.PI) # 輸出: 3.14159MathUtils.set_pi(3.14)
print(MathUtils.circle_area(5)) # 輸出: 78.5
- 靜態方法
通過使用@staticmethod
class StringUtils:@staticmethoddef reverse_string(s):"""靜態方法:反轉字符串"""return s[::-1]@staticmethoddef is_palindrome(s):"""檢查是否是回文"""return s == s[::-1]# 使用
print(StringUtils.reverse_string("hello")) # 輸出: olleh
print(StringUtils.is_palindrome("radar")) # 輸出: True# 也可以通過實例調用
utils = StringUtils()
print(utils.reverse_string("world")) # 輸出: dlrow
2.2.方法參數
- 位置參數
class User:def register(self, username, password, email):"""位置參數"""self.username = usernameself.password = passwordself.email = emailuser = User()
user.register("alice", "secret", "alice@email.com")
- 默認參數
class User:def register(self, username, password, email, is_active=True, role="user"):"""帶默認值的參數"""self.username = usernameself.password = passwordself.email = emailself.is_active = is_activeself.role = roleuser = User()
user.register("bob", "password", "bob@email.com") # 使用默認值
user.register("admin", "admin123", "admin@email.com", False, "admin")
- 關鍵字參數
class Config:def set_config(self, **kwargs):"""關鍵字參數"""for key, value in kwargs.items():setattr(self, key, value)config = Config()
config.set_config(host="localhost", port=8080, debug=True)
print(config.host) # 輸出: localhost
- 可變位置參數
class Calculator:def sum_all(self, *args):"""可變位置參數"""return sum(args)def average(self, *args):"""計算平均值"""if not args:return 0return sum(args) / len(args)calc = Calculator()
print(calc.sum_all(1, 2, 3, 4, 5)) # 輸出: 15
print(calc.average(10, 20, 30)) # 輸出: 20.0
2.3.特殊方法
- 構造和析構方法
class FileHandler:def __init__(self, filename):"""構造方法"""self.filename = filenameself.file = open(filename, 'r')print(f"文件 {filename} 已打開")def __del__(self):"""析構方法"""if hasattr(self, 'file') and self.file:self.file.close()print(f"文件 {self.filename} 已關閉")# 使用
handler = FileHandler("test.txt")
# 當對象被銷毀時自動調用__del__
- 字符串表示方法
class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):"""用戶友好的字符串表示"""return f"Person: {self.name}, {self.age}歲"def __repr__(self):"""開發者的字符串表示"""return f"Person('{self.name}', {self.age})"person = Person("張三", 25)
print(str(person)) # 輸出: Person: 張三, 25歲
print(repr(person)) # 輸出: Person('張三', 25)
- 運算符重載方法
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):"""加法運算符重載"""return Vector(self.x + other.x, self.y + other.y)def __sub__(self, other):"""減法運算符重載"""return Vector(self.x - other.x, self.y - other.y)def __mul__(self, scalar):"""乘法運算符重載"""return Vector(self.x * scalar, self.y * scalar)def __eq__(self, other):"""相等運算符重載"""return self.x == other.x and self.y == other.yv1 = Vector(2, 3)
v2 = Vector(1, 2)
v3 = v1 + v2 # Vector(3, 5)
v4 = v1 * 2 # Vector(4, 6)
print(v3.x, v3.y) # 輸出: 3 5
方法類型 | 裝飾器 | 第一個參數 | 用途 |
---|---|---|---|
實例方法 | 無 | self | 操作實例數據 |
類方法 | @classmethod | cls | 操作類屬性 |
靜態方法 | @staticmethod | 無 | 工具函數 |
屬性方法 | @property | self | 像屬性一樣訪問 |
抽象方法 | @abstractmethod | self/cls | 定義接口 |