我的Python学习之路05-附练习题

面向对象思想

面向对象编程

  • 类class与对象object
  • 对属于同一类事物的抽象叫类class
    • 比如汽车,门,猫。
    • 之前学习使用的都是Python自带的数据类,这节课我们学习自己定义类class
  • 某类事物中的一个具体的实例叫对象Object
    • 比如我家的那辆汽车,张伟办公室的大门,隔壁丽丽家的那只小花猫。
  • 类与对象的关系
  • 类定义封装了数据与方法,类就是对象的模板,可以批量生产出许多的对象。
    • 比如a=7,7其实是整形数字int类的一个实例。那int这个类还可以’复刻’出许许多多的整形对象。这些对象共有的特征就是:整数性。
  • 类(class)的变量是所有对象共享使用, 只有一个拷贝, 所有对象修改, 都可以被其他对象所见;
  • 对象(object)的变量由类的每个对象所拥有, 每个对象都包含自己的一份拷贝, 不会影响其他对象;

Python中一切皆对象

#Python中的一切对象都可以使用type查看它的类
#isinstance,issubclass的使用
class Animal():
    pass

class Cat(Animal):
    pass

c = Cat()

#isinstance判断一个对象实例是否属于该类型,但是isinstance的判断没有type准确,它无法判断子类的对象和父类的关系
print(isinstance(c, Cat))  # c是一只猫
print(isinstance(c, Animal))  # 向上判断 c是一只动物
print(type(c) is Cat)
print(type(c) is Animal)

#issubclass判断给定的两个类,前者是否是后者的子类
print('\n')
print(issubclass(Cat, Animal))  # 判断Cat类是否是Animal类的子类
print(issubclass(Animal, Cat))  # 判断Animal类是否是Cat类的子类

输出结果为:

True
True
True
False

True
False

类的设计与创建

#学生类设计
#总学生的人数,全部学生的姓名,已经毕业的学生的数量
#考试功能,分数大于60分,pass,,计入总分,否则 fail
#查分功能,如果考试次数
#查所有已经毕业学员的姓名。


class Student():
    student_total = 0
    student_graduated=0
    student_namelist=[]
    student_graduated_name_list=[]
    
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
        self.__score=0
        self.times=0#考试次数
        Student.student_total+=1
        Student.student_namelist.append(name)

    def exam(self,examscore):#def函数在类中定义叫方法method,以和类外部定义的函数区分
        if self.times==8:
            return 'you already qualified,winner,no need to take exam again'
        
        if examscore<60:        
            print('sorry,better luck next time!')
        elif examscore>100:
            print('you are cheating!')
        else:
            self.__score+=examscore
            self.times+=1
            print('OK!')
            if self.times==8 and self.__score/self.times>80:#如果参加了八次考试,且平均分数大于80分,即可毕业
                Student.student_graduated+=1
                Student.student_graduated_name_list.append(self.name)
                
            
    
    def check(self,):
        if self.times<8:
            return 'you need to do more {8-self.times} tests to graduate!'
        elif self.__score/self.times<80:
            return 'sorry,you are not qualified in ss,your mean score is {self.__score/self.times}'            
        else:
            return 'you alreay graduated,winner!'
        
    @classmethod
    def get_graducated_student(cls,):
        return cls.student_graduated
    
    @classmethod
    def get_graducated_student_list(cls,):
        return cls.student_graduated_name_list
    

类实例化对象并使用

#实例化并使用上面创建的类,并使用
ss=Student("zhangsan",18,"男")
ss.exam(70)
ss.check()

类成员一览

  • 数据成员
    • 类变量与实例变量
  • 方法成员
    • 类方法与实例方法
扩展阅读:私有成员
#私有成员:对类内部的属性及方法,通过在在标识符前加双 下划线__来实现的私有化
#即使是在成员名面前加了__,依旧可以访问到。
 #因为python使用一种 name mangling 技术,将 __membername替换成 _classname__membername
ss._Student__score

输出结果为:

70

类中的关键字与装饰器详解

类中的关键字

#关键字
# cls
# cls是指向类的指针,在类方法中第一个形参要命名为cls.

# self
# self是指向每个独立对象的指针.在实例方法中第一个形参被命名为self,以区别其它函数。 
#对象方法以self参数,类方法以cls参数来传递。

类中的装饰器

#这个的作用就是让全部结果都显示出来。
%config ZMQInteractiveShell.ast_node_interactivity='all'
#装饰器
#@staticmethod:类静态方法
#@classmethod:类方法


#@property—把函数调用伪装成对属性的访问,数据描述符属性的优先级高于实例名称空间中的同名成员。
# 使用@property,不用再像java中使用getter,setter方法去设置和访问类变量   
# 这时,也只有通过@property,才能对实例变量进行访问或设置,实现了对变量访问的控制,

class Student1():
    def __init__(self,name,age):  ###__init__实例初始化
        self.name = name       ####self:实例变量,变量的名字叫name
        self.__age=age
        
    @property #getter
    def name1(self):
        return self.name
    
    @name1.setter  # setter
    def name1(self,newname):
        self.name = newname
        
    @property #getter
    def age(self):
        return self.__age
    
    @age.setter  # setter
    def age(self,newage):
        self.__age = newage
        
# 上面这样设置的是类变量可以被类实例随意访问,修改。
# 注意,这里的name1,如果和实例变量name重名会导致,无限递归!!!
# RecursionError: maximum recursion depth exceeded while calling a Python object

# 但如果想让@property和类实例变量同名呢?  
# 将实例变量设置为私有(像age一样)就不会导致重名引发递归死机了
s1=Student1('jack',33)
s1.name1
s1.name1="zhangsan"
s1.name1

s1.age#getter
s1.age=22#setter
s1.age

输出结果为:

'jack'
'zhangsan'
33
22
扩展阅读 魔术方法,__*__
  • 魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,
  • 你可以定义自己想要的行为,这些会自动发生。
  • 它们经常是两个下划线包围来命名的

练习题:

完成公司类的设计

  • 设计以下公司类,并实例化不同对象进行检查
  • 类成员
    • 类下公司的总个数
  • 类方法
    • 返回公司类共有多少个公司实例
  • 实例变量
    • 公司名,简介,利润,销售额,总成本,雇员姓名,雇员人员。
  • 实例方法要求有:
    • 招聘人才(每招一个人会有成本产生,影响雇员列表,人数,总成本)
    • 解雇人员(每解雇一个人会有成本产生,影响雇员列表,人数 ,总成本)
    • 公司广告推广 ( 影响总成本 )
    • 交社保 ( 按公司雇员总人数计算,影响总成本 )
    • 交税 ( 按公司雇员总人数计算,影响总成本 )
    • 销售(按销售件数 * 价格计算销售额,利润按销售额 * 利润率进行计算利润。)
    • 获取公司雇员列表
    • 获取公司净利润
class Company():
    company_list=[]
    
    def __init__(self,name,intro,totalcost,employees):
        self.name=name
        self.intro=intro
        self.profit=0
        self.sales=0
        self.totalcost=totalcost
        self.employees=employees
        Company.company_list.append(name)
        
    @classmethod
    def get_company_list(cls,):
        return cls.company_list
    
    def recruit(self,newemployee,cost):
        self.employees.append(newemployee)
        self.totalcost-=cost
    
    def fire(self,employeename):
        self.employees.remove(employeename)
        
    def advertising(self,cost):
        self.totalcost-=cost
        
    def social_insurance(self):
        self.totalcost-=len(self.employees)*120
    
    def pay_tax(self):
        self.totalcost-=len(self.employees)*12
        
    def sale(self,price,totalcount):
        sales=price*totalcount
        self.sales+=sales
        self.profit+=sales*0.03
    
    def get_employees(self):
        return self.employees
    
    def get_profit(self):
        return self.profit
    
    def get_totalcost(self):
        return self.totalcost
    

employees=['张三1','张三2','张三3','张三4']    
cc=Company('百度','介绍百度公司',10000,employees)
cc2=Company('阿里','介绍阿里公司',20000,employees)
Company.get_company_list()
cc.recruit('李四',100)
cc.fire('张三1')
cc.advertising(3000)
cc.social_insurance()
cc.pay_tax()
cc.sale(100,1000)
cc.get_employees()
cc.get_profit()
cc.get_totalcost()
        
        

输出结果为:

['百度', '阿里']
['张三2', '张三3', '张三4', '李四']
3000.0
6372
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值