Python学习--Day 21

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
    # 定义set和get方法:
    # set赋值
    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) # 姓名:Amy,年龄:56,考试分数:59
print(stu.get_age()) # 56
  • 私有化的好处:①隐藏属性不被外界随意修改;②对外部只可以通过定义过的特定函数进行修改;③还可以对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)) # 不会打印对象属性__name等,
# 输出结果:
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
print(dir(stu)) # 会打印出'_Person__age', '_Person__name', '_Person__score',是代表类的属性,返回不出对象具有的私有化属性
# 输出结果
# ['_Person__age', '_Person__name', '_Person__score', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
  • 注意对比上面两个打印结果,打印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 # 注意是age调用,而不是property.setter,也就是要先有@property
    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) # 20,通过装饰器变为了可以外界访问的
s.__age = 67 # 调用setter函数进行修改
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))
# 输出结果:
# BMW以速度80在Route 66行驶了10.0个小时的时长。
  • 老师一直在帮助大家理解面向对象,主要是想说明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: # 学生类中使用了book类和Computer类
    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)
# 打印结果:
# Amy__MAC__pro__black__[<__main__.Book object at 0x0351E910>]

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: # 学生类中使用了book类和Computer类
    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)
# 结果:
# 进入子类方法
# Amy
  • 传参的子类方法重写怎么办?子类、父类的方法中都要添加参数项。
class Person:
    def __init__(self,name): # 加name
        self.name = name
class Student(Person):
    def __init__(self,name): # 加name
        print('进入子类方法')
        super().__init__(name) # 加name
s = Student('ji')
print(s.name)
  • 多个类的继承,参数的书写方式1:
    与父类一样的参数可以使用super()super(当前类名,self),其他的使用正常的self就好。
    super(当前类名,self)——多了一个判断功能,也就是判断当前类名是不是self类型。
class Person:
    def __init__(self,name): # 加name
        self.name = name
class Student(Person):
    def __init__(self,name,gender): # 加name
        super().__init__(name)
        self.gender = gender
class Doctor(Person):
    def __init__(self,name,manager,address):
        super().__init__(name)
        # 上面的代码也可以写成:super(Doctor,self).__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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
某公司雇员(Employee)包括经理(Manager),技术人员(Technician)和销售员(Salesman)。开发部经理(DeveloperManger),既是经理也是技术人员。销售部经理(SalesManager),既是经理也是销售员。 以Employee类为虚基类派生出Manager,Technician和Salesman类;再进一步派生出Developermanager和Salesmanager类。 Employee类的属性包括姓名、职工号、工资级别,月薪(实发基本工资加业绩工资)。操作包括月薪计算函数(pay()),该函数要求输入请假天数,扣去应扣工资后,得出实发基本工资。 Technician类派生的属性有每小时附加酬金和当月工作时数,及研究完成进度系数。业绩工资为三者之积。也包括同名的pay()函数,工资总额为基本工资加业绩工资。 Salesman类派生的属性有当月销售额和酬金提取百分比,业绩工资为两者之积。也包括同名的pay()函数,工资总额为基本工资加业绩工资。 Manager类派生属性有固定奖金额和业绩系数,业绩工资为两者之积。工资总额也为基本工资加业绩工资。 而DeveloperManager类,pay()函数是将作为经理和作为技术人员业绩工资之和的一半作为业绩工资。 SalesManager类,pay()函数则是经理的固定奖金额的一半,加上部门总销售额与提成比例之积,这是业绩工资。 编程实现工资管理。特别注意pay()的定义和调用方法:先用同名覆盖,再用运行时多态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值