155.私有化
- 私有化与封装:
__属性
就是将属性私有化,访问仅仅限于类中。
封装:针对私有化的属性才有,定义公有的set和get方法可以实现外部查看和修改。
class Person:
__age = 13
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 59
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.name,self.age,self.__score)
stu = Person('Amy',89)
print(stu)
stu.__score()
stu.__score() = 98
- 定义set和get方法以进行外部修改和查看:
示例:
class Person:
def __init__(self,name,age):
self.__name = name
self.__age = age
self.__score = 59
def set_age(self,age):
self.__age = age
def get_age(self):
return self.__age
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.__name,self.__age,self.__score)
stu = Person('Amy',89)
stu.set_age(56)
print(stu)
print(stu.get_age())
- 私有化的好处:①隐藏属性不被外界随意修改;②对外部只可以通过定义过的特定函数进行修改;③还可以对set函数进行编写以筛选赋值内容;④想拿到具体的数值可以使用定义过的get方法
156.私有化之property装饰器方式
- 使用
dir(对象或类名)
查看对象内的全部内容:包括系统自带的和自己定义的内容,包括函数和属性。其中对象可以是类名也可以是对象名称。
示例:
class Person:
def __init__(self,name,age):
self.__name = name
self.__age = age
self.__score = 59
stu = Person('Amy',89)
print(dir(Person))
print(dir(stu))
- 注意对比上面两个打印结果,打印
dir(Person)
不会返回'_Person__age', '_Person__name', '_Person__score'
,而打印dir(stu)
会打印出'_Person__age', '_Person__name', '_Person__score'
,这里是因为python底层做了一些变化,会自动将stu.__name
改名为_Person__name
,我们可以使用stu._Person__age
进行底层调用,也就是说这是一种伪装的私有化,在外界依旧可以访问到对应的变量,只不过python不建议通过这种方式,要少用。
使用stu._Person__age
进行底层调用的测试代码:
class Person:
def __init__(self,name,age):
self.__name = name
self.__age = age
self.__score = 59
stu = Person('Amy',89)
print(stu._Person__age)
- 开发常用的代码:优化后的私有化变量访问,使用
@property
进行私有化,可以让外面方便访问。在外界访问的时候直接使用装饰过的函数名进行访问就好。后面的set函数要基于上面的@property
,才能进行装饰。关键注意书写方式。
class Student:
def __init__(self,name,age):
self.name = name
self.__age = age
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
if age > 0 and age < 100:
self.__age = age
else:
print('No')
s = Student('peng',20)
s.name = 'xiaopeng'
print(s.__age)
s.__age = 67
print(s.__age)
157.继承中的has a
class Road:
def __init__(self,name,len):
self.road_len = len
self.road_name = name
class Car:
def __init__(self,name,speed):
self.car_name = name
self.car_speed = speed
def get_time(self,road):
return '{}以速度{}在{}行驶了{}个小时的时长。'.format(self.car_name,self.car_speed,road.road_name,road.road_len/self.car_speed)
def __str__(self):
return '车的名字是{},具有{}的速度'.format(self.car_name,self.car_speed)
route= Road('Route 66',800)
bmw = Car('BMW',80)
print(bmw.get_time(route))
- 老师一直在帮助大家理解面向对象,主要是想说明Student类中使用了Book类和Computer类。
class Computer:
def __init__(self,brand,type,color):
self.brand = brand
self.type = type
self.color = color
def online(self):
print('正在上网')
def __str__(self):
return self.brand + '__' +self.type+'__'+self.color
class Book:
def __init__(self,bname,author,number):
self.bname = bname
self.author = author
self.number = number
def __str__(self):
return self.bname +'__'+self.author+'__'+str(self.number)
class Student:
def __init__(self,name,computer,book):
self.name = name
self.computer = computer
self.books = []
self.books.append(book)
def __str__(self):
return self.name+'__'+str(self.computer)+'__'+str(self.books)
c = Computer('MAC','pro','black')
b = Book('盗墓笔记','南派三叔',10)
s = Student('Amy',c,b)
print(s)
158.补充has a
class Computer:
def __init__(self,brand,type,color):
self.brand = brand
self.type = type
self.color = color
def online(self):
print('正在上网')
def __str__(self):
return self.brand + '__' +self.type+'__'+self.color
class Book:
def __init__(self,bname,author,number):
self.bname = bname
self.author = author
self.number = number
def __str__(self):
return self.bname +'__'+self.author+'__'+str(self.number)
class Student:
def __init__(self,name,computer,book):
self.name = name
self.computer = computer
self.books = []
self.books.append(book)
def __str__(self):
return self.name+'__'+str(self.computer)+'__'+str(self.books)
def borrow_book(self,book1):
for bookread in self.books:
if bookread == book1:
break
else:
self.books.append(book1)
def show_book(self):
for book in self.books:
print(book.bname)
c = Computer('MAC','pro','black')
b = Book('盗墓笔记','南派三叔',10)
b2 = Book('Finance','Bodi',23)
s = Student('Amy',c,b)
print(s)
s.show_book()
s.borrow_book(b2)
s.show_book()
- 知识点:
has a:一个类中使用了另外一种自定义的类型
系统自带的类型:str、int、float、list、dict、tuple、set
自定义类型:自定义的类
159.继承
- is a:如果A是B,那么B是A的父类或基类
- Java中学过继承,大部分比较容易理解。
- 使用方法:
class 子类 (父类)
,默认继承object。 - 继承的知识点:几个子类具有相同的特性,通过继承机制精炼代码。
160.继承中的init
- 如果子类重写了父类的某方法,在调用的时候子类方法会覆盖父类方法。如果想引用父类的方法,要使用
super
,super()表示父类对象。在以后书写的时候,父类的初始化方法必须要记得使用,因为要顺便将父类的初始化动作也要完成super().__init__()
。
class Person:
def __init__(self):
self.age = 'Amy'
class Student(Person):
def __init__(self):
print('进入子类方法')
super().__init__()
s = Student()
print(s.age)
- 传参的子类方法重写怎么办?子类、父类的方法中都要添加参数项。
class Person:
def __init__(self,name):
self.name = name
class Student(Person):
def __init__(self,name):
print('进入子类方法')
super().__init__(name)
s = Student('ji')
print(s.name)
- 多个类的继承,参数的书写方式1:
与父类一样的参数可以使用super()
或super(当前类名,self)
,其他的使用正常的self
就好。
super(当前类名,self)
——多了一个判断功能,也就是判断当前类名是不是self类型。
class Person:
def __init__(self,name):
self.name = name
class Student(Person):
def __init__(self,name,gender):
super().__init__(name)
self.gender = gender
class Doctor(Person):
def __init__(self,name,manager,address):
super().__init__(name)
self.manager = manager
self.address = address
per = Person('Amy')
stu = Student('Tom','man')
doc = Doctor('Kim','Bob','China')
161.继承中的super使用
- super()的原则:
①.如果子类不定义__init__()
,默认就会调用父类的__init__()
方法
②.如果子类继承了父类也需要定义自己的__init__()
,需要在子类的__init__()
方法中使用super().__init__()
才能调用父类,同时我们要注意书写的时候要经常记得加上super()
父类的__init__()
,以顺利完成初始化,具体位置视情况而定
③.如何调用父类的__init__()
方法:有三种方式:super().__init__(参数)
或super(当前类名,self).__init__(参数)
或父类类名.__init__(self)
④.如果父类有eat()
方法,子类也有eat()
方法,那么程序执行的时候就先调用子类的eat()
。通常叫重写,是基于父类的函数功能不能满足子类的要求。
⑤.子类的方法中,可以调用父类的方法,使用super().方法名(参数)
就好了
162.继承练习
- 习题内容:
编写一个简单的工资管理程序,系统可以管理以下四类人:工人(worker)、销售员(salesman)、经理(manager)、销售经理(salemanager)。所有的员工都有员工号、姓名、工资等属性,有设置姓名、获取姓名、获取员工计算工资等方法。
1)工人:工人具有工作小时数和时薪的属性,工资计算方法为工作小时×时薪。
2)销售员:具有销售额和提成比例的属性,工资计算方法为销售额×提成比例。
3)经理:具有固定月薪的属性,工资计算方法为固定月薪。
4)销售经理:工资计算方法为销售额×提成比例+固定月薪。
根据以上要求设计合理的类,完成以下功能:
1)添加所有类型的人员
2)计算月薪
3)显示所有人的工资情况
下面是我的答案:
class Person:
salary = 0
def __init__(self,number,name):
self.name = name
self.number = number
def set_name(self,name):
self.name = name
def get_name(self):
return self.name
def get_number(self):
return self.number
def salary_count(self):
pass
class worker(Person):
def __init__(self,number,name,work_hours,salary_per_hour):
super(worker,self).__init__(number,name)
self.work_hours = work_hours
self.salary_per_hour = salary_per_hour
def salary_count(self):
self.salary = self.salary_per_hour * self.work_hours
return self.salary
def __str__(self):
return 'number of worker:{}, salary:{}'.format(self.number,self.salary)
class salesman(Person):
def __init__(self,number,name,goods_num,up_rate):
super(salesman,self).__init__(number,name)
self.goods_num = goods_num
self.up_rate = up_rate
def salary_count(self):
self.salary = self.goods_num * self.up_rate
return self.salary
def __str__(self):
return 'number of worker:{}, salary:{}'.format(self.number,self.salary)
class manager(Person):
def __init__(self,number,name,base_salary):
super(manager,self).__init__(number,name)
self.base_salary = base_salary
def salary_count(self):
self.salary = self.base_salary
return self.salary
def __str__(self):
return 'number of worker:{}, salary:{}'.format(self.number,self.salary)
class salemanager(Person):
def __init__(self,number,name,goods_num,up_rate,base_salary):
super(salemanager,self).__init__(number,name)
self.goods_num = goods_num
self.base_salary = base_salary
self.up_rate = up_rate
def salary_count(self):
self.salary = self.goods_num * self.up_rate + self.base_salary
return self.salary
def __str__(self):
return 'number of worker:{}, salary:{}'.format(self.number,self.salary)