1.2.1 面向对象详解(Django 基础学习细节)
Python 的面向对象编程(OOP)思想是 Django 框架设计的核心,也是开发复杂应用的必备技能。下面将对面向对象各知识点进行详细讲解,并配以大量代码示例。
一、类与对象、属性与方法
1. 定义类与创建对象
class Dog:
species = "Canis familiaris" # 类属性
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
def bark(self): # 实例方法
print(f"{self.name} says: Woof!")
# 创建对象
d1 = Dog("Tommy", 2)
d2 = Dog("Jerry", 3)
print(d1.name) # Tommy
print(d2.age) # 3
d1.bark() # Tommy says: Woof!
print(Dog.species) # Canis familiaris
说明:
- 类属性属于类本身,所有对象共享。
- 实例属性属于每个对象,互不干扰。
- 方法通过
self
访问实例属性和其他方法。
二、构造与析构函数
1. 构造函数(__init__
)
- 在创建对象时自动调用,用于初始化属性。
class User:
def __init__(self, username, email):
self.username = username
self.email = email
print(f"User {self.username} created!")
u = User("alice", "alice@demo.com")
# 输出: User alice created!
2. 析构函数(__del__
)
- 在对象销毁时自动调用(很少用,谨慎使用)。
class Temp:
def __init__(self, name):
self.name = name
def __del__(self):
print(f"Temp object {self.name} destroyed.")
t = Temp("t1")
del t
# 输出: Temp object t1 destroyed.
三、类方法、静态方法、实例方法
1. 实例方法
- 默认第一个参数是
self
,表示对象自身。
class Cat:
def say(self):
print("Meow")
c = Cat()
c.say()
2. 类方法(@classmethod)
- 第一个参数是
cls
,表示类本身,可用来创建对象或访问类属性。
class Person:
count = 0
def __init__(self, name):
self.name = name
Person.count += 1
@classmethod
def show_count(cls):
print(f"Total persons: {cls.count}")
Person("Ann")
Person("Bob")
Person.show_count() # Total persons: 2
3. 静态方法(@staticmethod)
- 无需
self
或cls
,逻辑通常与类相关但不依赖类属性或实例属性。
class MathUtil:
@staticmethod
def add(a, b):
return a + b
print(MathUtil.add(3, 4)) # 7
四、继承、多态、super
1. 继承
- 子类自动拥有父类的属性和方法。
class Animal:
def speak(self):
print("Animal speaks.")
class Dog(Animal):
def speak(self):
print("Dog barks.")
d = Dog()
d.speak() # Dog barks.
2. 多重继承
class A:
def foo(self):
print("A")
class B:
def bar(self):
print("B")
class C(A, B):
pass
c = C()
c.foo() # A
c.bar() # B
3. 多态
- 父类引用可以指向子类对象,表现出不同的行为。
class Bird:
def fly(self):
print("Bird flies.")
class Duck(Bird):
def fly(self):
print("Duck flies.")
def let_fly(obj):
obj.fly()
b = Bird()
d = Duck()
let_fly(b) # Bird flies.
let_fly(d) # Duck flies.
4. super() 用法
- 用于调用父类方法,保证正确的继承链。
class Base:
def hello(self):
print("Base says hello")
class Sub(Base):
def hello(self):
print("Sub says hi")
super().hello()
s = Sub()
s.hello()
# 输出:
# Sub says hi
# Base says hello
五、魔法方法(特殊方法)
Python 内建许多以双下划线开头结尾的方法,称为魔法方法,可自定义对象行为。
1. __str__
和 __repr__
class Book:
def __init__(self, title):
self.title = title
def __str__(self):
return f"Book: {self.title}"
def __repr__(self):
return f"Book('{self.title}')"
b = Book("Python")
print(str(b)) # Book: Python
print(repr(b)) # Book('Python')
2. __getitem__
、__setitem__
- 让对象支持索引访问,像列表/字典一样。
class MyList:
def __init__(self, data):
self.data = data
def __getitem__(self, idx):
return self.data[idx]
def __setitem__(self, idx, value):
self.data[idx] = value
ml = MyList([1,2,3])
print(ml[1]) # 2
ml[1] = 99
print(ml[1]) # 99
3. __call__
- 让对象能像函数一样被调用。
class Greeter:
def __init__(self, name):
self.name = name
def __call__(self, msg):
print(f"{self.name} says: {msg}")
g = Greeter("Alice")
g("Hello!") # Alice says: Hello!
六、属性(property装饰器,getter/setter)
1. property装饰器
- 用于把方法变成属性,可以控制读取、写入、删除行为(安全、简洁)。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("radius must be positive")
self._radius = value
@property
def area(self):
return 3.1416 * self._radius ** 2
c = Circle(5)
print(c.radius) # 5
print(c.area) # 78.54
c.radius = 10 # 调用 setter
# c.radius = -1 # 会抛出异常
2. 只读属性
class Student:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
s = Student("Ann")
print(s.name) # Ann
# s.name = "Bob" # AttributeError: can't set attribute
七、实用小结
- 类和对象是代码复用和业务抽象的基础。
- 构造/析构函数用于资源管理和初始化。
- 三种方法(实例、类、静态)方便不同层级的操作。
- 继承和多态让代码扩展性更强。
- 魔法方法让对象表现更灵活(如自定义打印、索引、调用等)。
- property装饰器让属性读写更安全和优雅。