Python基础知识(七)
一、面向对象
(一)、面向对象特征
1、封装
使用importlib 可以在测试时,在控制台上看到每个集合的详细信息。
在.py文件中,repr(self):定义在控制台上的输出效果
str(self):定义打印的效果
class Book:
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
def print_info(self):
print(self.title,self.price,self.author)
if __name__ == '__main__':
book = Book('Python经典',price = 29.0,author = 'Tom')
book.print_info()
运行结果:
class Book:
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
def __str__(self):
return '[图书:{},定价:{}]'.format(self.title,self.price)
def __repr__(self):
return '<图书:{}>'.format(self.title)
def print_info(self):
print(self.title,self.price,self.author)
控制台上:
>>>import main
>>>import importlib
>>>importlib.reload(main)
<module 'main' from 'E:\\mypython01\\main.py'>
>>>print(b)
[图书:Python,定价:0.0]
>>
>>>print(b)
[图书:Python,定价:0.0]
>>>importlib.reload(main)
<module 'main' from 'E:\\mypython01\\main.py'>
>>>b = main.Book('C#')
>>>b
<图书:C# at 0x1959451130232>
注:下面例子中的count变量 属于图书的信息但是和实例无关的变量不要写在__init__里,写在类里。
class Book:
count = 0
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
def __repr__(self):
return '<图书:{} at 0x{}>'.format(self.title,id(self))
def __str__(self):
return '[图书:{},定价:{}]'.format(self.title,self.price)
def print_info(self):
print(self.title,self.price,self.author)
if __name__ == '__main__':
book = Book('Python经典',price = 29.0,author = 'Tom')
book.count += 1
book2 = Book('Flask')
book.count +=1
book3 = Book('ASP.net')
book.count +=1
print('图书数量:{}'.format(book.count))
运行结果:
代码改进:
class Book:
count = 0
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
Book.count +=1
#删除对象执行
def __del__(self):
Book.count -= 1
def __repr__(self):
return '<图书:{} at 0x{}>'.format(self.title,id(self))
def __str__(self):
return '[图书:{},定价:{}]'.format(self.title,self.price)
def print_info(self):
print(self.title,self.price,self.author)
if __name__ == '__main__':
book = Book('Python经典',price = 29.0,author = 'Tom')
book2 = Book('Flask')
book3 = Book('ASP.net')
del(book3)
运行结果:
注:全局的静态变量可以通过实例来调用,如果不改变值,其值和全局相同,如果改变count值,得到的变量值book2.count和全局变量无关。
class Book:
count = 0
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
Book.count +=1
def __repr__(self):
return '<图书:{} at 0x{}>'.format(self.title,id(self))
def __str__(self):
return '[图书:{},定价:{}]'.format(self.title,self.price)
def print_info(self):
print(self.title,self.price,self.author)
if __name__ == '__main__':
book = Book('Python经典',price = 29.0,author = 'Tom')
book2 = Book('Flask')
book3 = Book('ASP.net')
print('图书数量:{}'.format(Book.count))
print('图书数量:{}'.format(book2.count))
book2.count = 99
print('图书数量:{}'.format(Book.count))
print('图书数量:{}'.format(book2.count))
运行结果:
注:static_mathod():是静态函数,逻辑上与实例无关,不能通过实例调用(book2.static_method())在前面加上@static_method使得静态函数既可以被类调用,也可以被函数调用。
定义只能被类调用的函数:
class Book:
count = 0
def __init__(self,title,price =0.0,author = None):
self.title = title
self.price = price
self.author = author
Book.count += 1
def __repr__(self):
return '<图书:{} at 0x{}>'.format(self.title,id(self))
def __str__(self):
return '[图书:{},定价:{}]'.format(self.title,self.price)
def print_info(self):
print(self.title,self.price,self.author)
def cls_method(cls): #未绑定的方法或者是类的方法
print('类函数')
def static_method():
print('静态函数,逻辑上与实例无关')
if __name__ == '__main__':
book = Book('Python经典',price = 29.0,author = 'Tom')
book2 = Book('Flask')
book3 = Book('ASP.net')
Book.cls_method(book2)
Book.static_method()
运行结果:
过滤一下别人所赋的值
方法一:写一个函数
import datetime
class Student:
def __init__(self,name,birthdate):
self.name = name
self.birthdate = birthdate
def get_age(self):
return datetime.date.today().year - self.birthdate.year
if __name__ == '__main__':
s = Student('Tom',datetime.date(1992,3,1))
print(s.birthdate)
print(s.get_age())
运行结果:
方法二:使用装饰器@property进行过滤,使age和成员属性一致
import datetime
class Student:
def __init__(self,name,birthdate):
self.name = name
self.birthdate = birthdate
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
if __name__ == '__main__':
s = Student('Tom',datetime.date(1992,3,1))
print(s.birthdate)
print(s.age)
运行结果:
注:@property和@age.setter、@age.deleter配合使用
import datetime
class Student:
def __init__(self,name,birthdate):
self.name = name
self.birthdate = birthdate
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
@age.setter
def age(self,value):
raise AttributeError('禁止赋值年龄!')
@age.deleter
def age(self):
raise AttributeError ('年龄不能删除')
if __name__ == '__main__':
s = Student('Tom',datetime.date(1992,3,1))
print(s.birthdate)
print(s.age)
s.birthdate = datetime.date(1982,8,2)
print(s.birthdate)
print(s.age)
运行结果:
年龄(age)不能更改和删除
import datetime
class Student:
def __init__(self,name,birthdate):
self.name = name
self.birthdate = birthdate
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
@age.setter
def age(self,value):
raise AttributeError('禁止赋值年龄!')
@age.deleter
def age(self):
raise AttributeError ('年龄不能删除')
if __name__ == '__main__':
s = Student('Tom',datetime.date(1992,3,1))
print(s.birthdate)
print(s.age)
s.birthdate = datetime.date(1982,8,2)
s.age = 20
print(s.birthdate)
print(s.age)
运行结果:
import datetime
class Student:
def __init__(self,name,birthdate):
self.name = name
self.birthdate = birthdate
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
@age.setter
def age(self,value):
raise AttributeError('禁止赋值年龄!')
@age.deleter
def age(self):
raise AttributeError ('年龄不能删除')
if __name__ == '__main__':
s = Student('Tom',datetime.date(1992,3,1))
print(s.birthdate)
print(s.age)
s.birthdate = datetime.date(1982,8,2)
del(s.age)
print(s.age)
运行结果:
2、继承
有利于代码的重用
基类和派生类的定义:
main01.py文件
class Employee:
def __init__(self,department,name,birthdate,salary):
self.department = department
self.name = name
self.birthdate = birthdate
self.salary = salary
def __repr__(self):
return '<员工:{}>'.format(self.name)
def working(self):
print('员工:{},在工作...'.format(self.name))
class Programer(Employee):
def __init__(self,department,name,birthdate,salary,specialty,project):
super().__init__(department,name,birthdate,salary)
self.specialty = specialty
self.project = project
def working(self):
print('程序员:{}在开发项目:{}...'.format(self.name,self.project))
控制台上:
>>>import main01
>>>import datetime
>>>import importlib
>>>p = main01.Programer('技术部','Peter',datetime.date(1990,3,1),8000,'Python','CRM')
p
<员工:Peter>
>>>p.salary
8000
>>>p.specialty
'Python'
注:当某一个值是通过计算得到的,这时考虑使用属性@property
import datetime
class Employee:
def __init__(self,department,name,birthdate,salary):
self.department = department
self.name = name
self.birthdate = birthdate
self.salary = salary
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
def give_raise(self,percent,bonus=.0):
self.salary = self.salary * (1 + percent +bonus)
def __repr__(self):
return '<员工:{}>'.format(self.name)
def working(self):
print('员工:{},在工作...'.format(self.name))
class Programer(Employee):
def __init__(self,department,name,birthdate,salary,specialty,project):
super().__init__(department,name,birthdate,salary)
self.specialty = specialty
self.project = project
def working(self):
print('程序员:{}在开发项目:{}...'.format(self.name,self.project))
if __name__ == '__main__':
p = Programer('技术部','Peter',datetime.date(1990,3,3,),8000,'Flask','CRM')
print(p)
print(p.department)
print(p.salary)
p.give_raise(.2,.1)
print(p.salary)
p.working()
print(p.age)
运行结果:
举例:
import datetime
class Employee:
def __init__(self,department,name,birthdate,salary):
self.department = department
self.name = name
self.birthdate = birthdate
self.salary = salary
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
def give_raise(self,percent,bonus=.0):
self.salary = self.salary * (1 + percent +bonus)
def __repr__(self):
return '<员工:{}>'.format(self.name)
def working(self):
print('员工:{},在工作...'.format(self.name))
class Programer(Employee):
def __init__(self,department,name,birthdate,salary,specialty,project):
super().__init__(department,name,birthdate,salary)
self.specialty = specialty
self.project = project
def working(self):
print('程序员:{}在开发项目:{}...'.format(self.name,self.project))
class HR(Employee):
def __init__(self,department,name,birthdate,salary,qualification_level = 1):
Employee.__init__(self,department,name,birthdate,salary)
self.qualification_level = qualification_level
def working(self):
print('人事:{}正在面试新员工...'.format(self.name))
if __name__ == '__main__':
p = Programer('技术部','Peter',datetime.date(1990,3,3,),8000,'Flask','CRM')
print(p)
print(p.department)
print(p.salary)
p.give_raise(.2,.1)
print(p.salary)
p.working()
print(p.age)
hr = HR('人事部','Marry',datetime.date(1992,4,4),6000,qualification_level=3)
hr.give_raise(.1)
print(hr.salary)
hr.working()
运行结果:
3、多态:属于同一类型的不同实例,对同一个消息做出不同的响应能力。
包含的关系
import datetime
class Department:
def __init__(self,department,phone,manager):
self.department = department
self.phone = phone
self.manager = manager
def __repr__(self):
return '<部门:{}>'.format(self.department)
class Employee:
def __init__(self,department:Department,name,birthdate,salary):
self.department = department
self.name = name
self.birthdate = birthdate
self.salary = salary
@property
def age(self):
return datetime.date.today().year - self.birthdate.year
def give_raise(self,percent,bonus=.0):
self.salary = self.salary * (1 + percent +bonus)
def __repr__(self):
return '<员工:{}>'.format(self.name)
def working(self):
print('员工:{},在工作...'.format(self.name))
class Programer(Employee):
def __init__(self,department,name,birthdate,salary,specialty,project):
super().__init__(department,name,birthdate,salary)
self.specialty = specialty
self.project = project
def working(self):
print('程序员:{}在开发项目:{}...'.format(self.name,self.project))
class HR(Employee):
def __init__(self,department,name,birthdate,salary,qualification_level = 1):
Employee.__init__(self,department,name,birthdate,salary)
self.qualification_level = qualification_level
def working(self):
print('人事:{}正在面试新员工...'.format(self.name))
if __name__ == '__main__':
dep = Department('技术部','010-87718391','张大三')
p = Programer(dep,'Peter',datetime.date(1990,3,3),8000,'Python,Flask','XMall')
p.give_raise(.2,.1)
print(p.salary)
print(p.department.phone)
print(p.department.manager)
运行结果: