1. 面向对象基础概念
-
类(Class):对象的蓝图,定义对象的属性和方法。
-
对象(Object):类的实例,具有具体的属性和行为。
-
属性(Attribute):对象的状态(变量)。
-
方法(Method):对象的行为(函数)。
类对象支持两种操作:属性引用和实例化。
属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name
python">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!")# 创建对象
my_dog = Dog("Buddy", 3)
print(my_dog.name) # 输出: Buddy
my_dog.bark() # 输出: Buddy says: Woof!
练习:
定义一个Person 类,有出生日期跟姓名两个属性,有一个方法,根据出生日期计算年龄age方法。
python">
from datetime import date,datetime
from dateutil.relativedelta import relativedelta
class Person:name =''born_date =''def __init__(self, name, borndate):self.name = nameself.born_date = borndatedef age(self):today = date.today()birth = date.fromisoformat(self.born_date)age = today.year-birth.yearif((today.month, today.day) < (birth.month, birth.day)):age -=1return agep1 = Person('zhangsan','1983-10-01')
print(p1.name)
print(p1.age())
p2 = Person('zhangsan','1998-05-01')
date1 = datetime.strptime(p1.born_date,'%Y-%m-%d')
date2 = datetime.strptime(p2.born_date,'%Y-%m-%d')
delta = relativedelta(date1,date2)
print(f"两个日期相差 {delta.years} 年 {delta.months} 月 {delta.days} 天")
输出:
zhangsan
41
两个日期相差 -14 年 -7 月 0 天
计算日期差还可以用dateutil.relativedelta,省去使用date的计算year,month去算。
继承
子类继承父类的属性和方法,并可以扩展或覆盖它们。
python">
from datetime import date,datetimeclass Person:name =''born_date =''def __init__(self, name, borndate):self.name = nameself.born_date = borndatedef age(self):today = date.today()birth = date.fromisoformat(self.born_date)age = today.year-birth.yearif((today.month, today.day) < (birth.month, birth.day)):age -=1return age
class Student(Person):StudentID =''scores =[]def __init__(self,name,borndate, StudentID, scores):super().__init__(name, borndate)self.StudentID = StudentIDself.scores = scoresdef avg(self):return sum(self.scores)/ len(self.scores)
s1 = Student('zhangsan','1983-10-01','x0001',[80,90,100,90])
print(f'studentid:{s1.StudentID},age:{s1.age()},avg:{str(s1.avg())}')
s2 = Student('zhangsan','1998-05-01','x0002',[60,80,74,69])
print(f'studentid:{s2.StudentID},age:{s2.age()},avg:{str(s2.avg())}')
输出:
studentid:x0001,age:41,avg:90.0
studentid:x0002,age:26,avg:70.75
封装(Encapsulation)
通过访问控制保护对象的内部状态。
python">class BankAccount:def __init__(self, balance):self.__balance = balance # 私有属性(双下划线开头)def deposit(self, amount):if amount > 0:self.__balance += amountdef get_balance(self): # 公共方法访问私有属性return self.__balanceaccount = BankAccount(1000)
# account.__balance # 错误!无法直接访问私有属性
print(account.get_balance()) # 输出: 1000
注意:__private_attrs两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 :self.__private_attrs
直接访问注释掉的私有属性,pycharm没有提示,报错日志:
Traceback (most recent call last):
File "D:\Program Files\Python\Lib\site-packages\IPython\core\interactiveshell.py", line 3508, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-bc064a4419d4>", line 1, in <module>
runfile('D:/pythonProject128/learn/7.8.4.py', wdir='D:/pythonProject128/learn')
File "C:\Program Files\JetBrains\PyCharm Community Edition 2021.3.2\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2021.3.2\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "D:/pythonProject128/learn/7.8.4.py", line 14, in <module>
print(account.__balance)
AttributeError: 'BanckAccount' object has no attribute '__balance'
多态(Polymorphism)
不同对象对同一方法做出不同响应。
python">class Cat:def speak(self):print("Miao...")class Dog:def speak(self):print("wang...")def animal_sound(animal):animal.speak()cat = Cat()
dog = Dog()
animal_sound(cat) # 输出: Miao
animal_sound(dog) # 输出: wang
练习:几何图形计算:实现 Circle、Rectangle 类,计算面积和周长。
python">import mathclass Circle:def __init__(self, radius):self.radius = radiusdef area(self):return math.pi * self.radius**2def circumference(self):return 2 * math.pi * self.radiusclass Rectangle:def __init__(self, length, width):self.length = lengthself.width = widthdef area(self):return self.length * self.widthdef perimeter(self): # 周长通常称为perimeter,而不是circumference(周长)return 2 * (self.length + self.width)# 创建Circle实例并计算面积和周长
circle = Circle(5)
print("Circle Area:", circle.area())
print("Circle Circumference:", circle.circumference())# 创建Rectangle实例并计算面积和周长
rectangle = Rectangle(4, 6)
print("Rectangle Area:", rectangle.area())
print("Rectangle Perimeter:", rectangle.perimeter())
输出:
Circle Area: 78.53981633974483
Circle Circumference: 31.41592653589793
Rectangle Area: 24
Rectangle Perimeter: 20