Python基础学习笔记7

一、面向过程和面向对象

编程界的两大阵营

二、类和对象

Python中一切皆对象
-不同的数据类型属性不同的类
-使用内置函数type()查看对象的数据类型

  • 自定义类:
class 类名():
	pass
  • 创建对象:对象名=类名()

2.1类的组成

-类属性:直接定义在类中,方法外的变量称为类属性,被该类的所有对象所共享,使用类名打点访问
-实例属性:定义在__init()__方法中,使用self打点的变量称为实例属性
-实例方法:定义在类中,方法带在默认参数self的函数称为实例方法,使用对象名打点访问的方法
-静态方法:使用@staticmethod修饰的主法,使用类名直接访问的方法
-类方法:使用@classmethod修饰的方法,带有默认参数cls,使用类名打点访问

class Student:
    #类的属性:类中、方法外的变量
    school = 'znmd'

    #初始方法__init__
    def __init__(self,xm,age):#xm,age,是方法的参数,局部变量
        #=左侧是实例属性,=右侧是局部变量
        self.name = xm #将局部变量的值赋给实例属性self.name
        self.age = age #实例属性的名称与局部变量的名称相同了

    #实例方法
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

    #类方法
    @classmethod
    def cm(cls):
        print('这里是一个类方法,不能调用实例属性和实例方法')
        # print(self.name) ×
        # self.show() ×

    #静态方法
    @staticmethod
    def sm():
        print('这里是一个静态方法,不能调用实例属性和实例方法')

#类的组成部分的使用
#创建对象 在创建对象时,系统自动调用__init__方法
stu = Student('jww', 18) #只能传2个,因为__init__方法中自定义的变量有2个
#使用实例属性,使用对象名,打点使用
print(stu.name, stu.age)
#使用类属性,使用类名,打点使用
print(Student.school)
#使用实例方法,使用对象名,打点调用实例方法
stu.show()
#使用类方法,使用类名,打点调用类方法
Student.cm()
#使用类名打点调用静态方法
Student.sm()

2.2创建对象

类是模板,可以创建N个对象,每个对象的属性名是相同的,属性值是不同的
Python是动态语言,在创建对象之后,可以动态地绑定属性和方法

  • 创建对象
class Student:
    #类的属性:类中、方法外的变量
    school = 'znmd'

    #初始方法__init__
    def __init__(self,xm,age):#xm,age,是方法的参数,局部变量
        #=左侧是实例属性,=右侧是局部变量
        self.name = xm #将局部变量的值赋给实例属性self.name
        self.age = age #实例属性的名称与局部变量的名称相同了

    #实例方法
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

#创建N个对象
stu = Student('jww', 18)
stu2 = Student('yjh', 20)
stu3 = Student('hjs', 20)
stu4 = Student('qsr', 21)
Student.school = 'svt' #值被这个类的所有对象所共享
print(stu.name, stu.age, stu.school)

#将对象放到组合数据类型中存储,存储到列表中
lst = [stu, stu2, stu3, stu4]
for item in lst: # item的数据类型为Student,item是一个Student类型的对象
    item.show() #对象名,打点调用实例方法
  • 动态绑定属性和方法
class Student:
    #类的属性:类中、方法外的变量
    school = 'znmd'

    #初始方法__init__
    def __init__(self,xm,age):#xm,age,是方法的参数,局部变量
        #=左侧是实例属性,=右侧是局部变量
        self.name = xm #将局部变量的值赋给实例属性self.name
        self.age = age #实例属性的名称与局部变量的名称相同了

    #实例方法
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

#创建2个Student类型的对象
stu = Student('jww', 18)
stu2 = Student('hjs', 20)
print(stu.name, stu.age)
print(stu2.name, stu2.age)

## 为stu2绑定实例属性
stu2.gender = '男'
print(stu2.name, stu2.age, stu2.gender)

## 动态绑定方法
def introduce():
    print('我是一个普通的函数,我被动态绑定成为stu2对象的方法')

stu2.fun = introduce #不能带上(),带()为方法调用,没有()为动态绑定
#使用对象名打点调用方法
stu2.fun()

2.3访问权限限制

访问限制:
属性或方法添加单下划线、双下划线、首尾双下划线,限制访问权限

  • 单下划线:
    以单下划线开头,表示protected受保护的成员,只允许类本身和子类进行访问,可以通过对象名访问

  • 双下划线:
    双下划线表示private私有的成员,只允许定义该方法的类本身访问,不能通过类的对象访问,但可以通过以下方式访问”对象名._类名__xxx“方式访问(不建议使用)

  • 首尾双下划线:
    表示特殊的方法,一般是系统定义的名字

class Student(): ##()可加可不加
    # 首尾双下划线,表示特殊的方法,系统定义
    def __init__(self,name,age,gender):
        self._name = name #以单下划线开头,表示是受保护的成员,只能类本身和子类访问
        self.__age = age #以双下划线开头,表示是私有的,只能类本身访问
        self.gender = gender #普通的实例属性,在类的外部和内部以及子类都可以访问

    # 以单下划线开头,表示是受保护的方法
    def _fun1(self):
        print('子类和本身可以访问')

    # 以双下划线开头,表示是私有的
    def __fun2(self):
        print('只有定义的类可以访问')

    # 普通的实例方法,在类的外部使用对象名打点访问,在类的内部使用self打点访问
    def show(self):
        self._fun1() #类本身访问受保护的方法
        self.__fun2() #类本身访问私有的方法
        print(self._name) #类本身访问受保护的实例属性
        print(self.__age) #类本身访问私有的实例属性

if __name__ == '__main__':
    #创建一个Student类型的对象
    stu = Student('jww', 20, '男')
    #访问受保护的实例属性
    print(stu._name)
    #访问私有的实例属性
    # print(stu.__age) ×程序报错,出了类的定义范围
    #访问受保护的实例方法
    stu._fun1()
    #访问私有的实例方法
    # stu.__fun2() ×程序报错,出了类的定义范围

    #使用以下形式访问类对象的私有成员
    print(stu._Student__age)
    stu._Student__fun2()

三、面向对象的三大特征

3.1封装

  • 封装
    -隐藏内部细节,提高程序的安全性(健壮性)
    -使用 @propety 和 @函数名.setter
class Student:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    def show(self):
        print(f'我叫:{self.__name},我今年:{self.__age}岁了')

# if __name__ == '__main__':
#     #程序运行没有报错,但是运行结果不符合实际情况,年龄被赋予了不正确的值,所有程序不够安全
#     stu = Student('jww',-23)
#     stu.show()

class Student:
    def __init__(self,name):
        self.__name = name

    # 使用@property
    @property
    def age(self): #设置只读属性
        return self.__age

    # 设置赋值操作
    @age.setter
    def age(self,value):
        if value<0 or value>130:
                print('年龄不在正确的范围内,设置的年龄范围应该是0-130之间')
                self.__age = 18 #设置默认值
        else:
                self.__age = value

    def show(self):
            print(f'我叫:{self.name},今年:{self.__age}岁了')

if __name__ == '__main__':
    #创建Student类型的对象
    stu = Student('hjs')
    stu.age = -23
    print(stu.age)

3.2继承

  • 继承
    -实现继承,表示这个类拥有了被继承类的所有公有成员和受保护成员,被继承的类称为父类或基类,新的类称为子类或派生类
    -作用:实现代码的复用,通过继承可以理顺类与类之间的关系
    -语法结构
class 类名(super_class_lst):
	pass
class Person: #默认继承了object类
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁了')

#Student类继承Person类
class Student(Person):
    #编写初始化方法
    def __init__(self,name,age,stuno):
        #调用父类的初始化方法
        super().__init__(name,age) #给name和age进行赋值
        self.stuno = stuno #给自己特有的属性进行赋值

#Doctor类继承Person类
class Doctor(Person):
    def __init__(self,name,age,department):
        #调用父类的初始化方法
        Person.__init__(self,name,age) #给name和age进行赋值
        self.department = department #给自己特有的属性进行赋值

if __name__ == '__main__':
    #创建Student类的对象
    stu = Student('jww',20,'msb1001')
    stu.show()
    
    #创建Doctor类的对象
    doctor = Doctor('hjs',32,'外科')
    doctor.show()

3.2.1多继承

  • 多继承
    -一个子类可以有多个“直接父类”,具备“多个父类”的特点
class FatherA():
    def __init__(self,name):
        self.name = name

    def showA(self):
        print('父类A中的方法')

class FatherB():
    def __init__(self,age):
        self.age = age

    def showB(self):
        print('父类B中的方法')

class Son(FatherA,FatherB):
    def __init__(self,name,age,gender):
        FatherA.__init__(self,name) #给name赋值
        FatherB.__init__(self,age) #给age赋值
        self.gender = gender

if __name__ == '__main__':
    son = Son('jww',20,'男')
    son.showA()
    son.showB()

3.2.2方法重写

  • 方法重写
    -当父类(基类)中的某个方法不完全适合子类(派生类)时,就需要在子类中重写父类的方法
    -子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
class Person: #默认继承了object类
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁了')

#Student类继承Person类
class Student(Person):
    #编写初始化方法
    def __init__(self,name,age,stuno):
        #调用父类的初始化方法
        super().__init__(name,age) #给name和age进行赋值
        self.stuno = stuno #给自己特有的属性进行赋值

    #重写父类的方法
    def show(self):
        #可以调用父类的show方法,也可以重新编写实现方法的代码
        #调用父类的方法
        super().show()
        #再编写自己个性化的内容
        print(f'我的学号是:{self.stuno}')

#Doctor类继承Person类
class Doctor(Person):
    def __init__(self,name,age,department):
        #调用父类的初始化方法
        Person.__init__(self,name,age) #给name和age进行赋值
        self.department = department #给自己特有的属性进行赋值

    #重写父类的方法
    def show(self):
        #重新编写方法的实现代码
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁了,我的工作科室是:{self.department}')

if __name__ == '__main__':
    #创建Student类的对象
    stu = Student('jww',20,'svt1001')
    stu.show()

    #创建Doctor类的对象
    doctor = Doctor('hjs',32,'外科')
    doctor.show()

3.2.3object类

  • object类
    -object类是所有类的父类,因此所有类都有object类属性和方法
    -内置函数dir()可以查看指定对象的所有属性
    -object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()重写
print(dir(object))
#Person默认继承object类,所以object可以省略不写
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},今年{self.age}岁了')


    #重写__str__方法
    def __str__(self):
        return '这是一个人类,具有name和age两个实例属性'

if __name__ == '__main__':
    #创建了一个Person类型的对象
    per = Person('jww',20)
    print(dir(per))
    print('--------------------------------------------------')
    print(per) #当直接输出对象名时,默认调用__str__()方法
    print(per.__str__())
    print('--------------------------------------------------')
    #Person类的对象,调用父类的__dir__方法
    #以下这两句代码功能相同
    print(per.__dir__())
    print(dir(per))

3.3多态

  • 多态
    -多态即“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
    -Python语言中的多态,不关心对象的数据类型,不关心是否具有继承关系,只关心对象是否具有同名的行为(方法)
class Person():
    def eat(self):
        print('人,吃五谷杂粮')

class Cat():
    def eat(self):
        print('猫,喜欢吃鱼')

class Dog():
    def eat(self):
        print('狗,喜欢啃骨头')
        
def fun(obj): # 函数的定义,obj是函数的形式参数
    obj.eat() #对象名打点调用eat方法

if __name__ == '__main__':
    per = Person() #创建Person类的对象per
    cat = Cat() #创建Cat类的对象cat
    dog = Dog() #创建Dog类的对象dog

    #调用fun函数
    fun(per)
    fun(cat)
    fun(dog)

四、特殊方法和特殊属性

4.1特殊方法

Python中的运算实际上是通过调用特殊方法实现的
特殊方法

a = 10
b = 20
print(dir(a))
print('加法:',a.__add__(b))
print('减法:',a.__sub__(b))
print(f'{a}<{b}吗:',a.__lt__(b))
print(f'{a}<={b}吗:',a.__le__(b))
print(f'{a}=={b}吗:',a.__eq__(b))
print(f'{a}>{b}吗:',a.__gt__(b))
print(f'{a}>={b}吗:',a.__ge__(b))
print(f'{a}!={b}吗:',a.__ne__(b))

4.2特殊属性

特殊属性

class A:
    pass
class B:
    pass

class C(A,B):
    def __init__(self,name,age):
        self.name = name
        self.age = age

if __name__ == '__main__':
    a = A() #创建A类的对象
    b = B() #创建B类的对象
    c = C('jww',20) #创建C类的对象
    # 对象的属性字典
    print(a.__dict__)
    print(c.__dict__)
    # 对象所属的类
    print(a.__class__)
    print(b.__class__)
    print(c.__class__)
    # 类的父类,结果是一个元组
    print(A.__bases__)
    print(C.__bases__)
    # 类的父类,如果是继承多个父类,结果是第一个父类
    print(A.__base__)
    print(C.__base__)

    print(A.__mro__) # A类继承了object类
    print(C.__mro__) # C类继承了A、B类,A、B类继承了object类

    #获取类的子类列表
    print(A.__subclasses__()) # A类的子类为C类
    print(C.__subclasses__()) # C类没有子类,空列表

五、实战——计算圆的面积和周长

class Circle:
    def __init__(self,r):
        self.r = r

    #计算圆的面积
    def get_area(self):
        return 3.14*self.r*self.r
    #计算圆的周长
    def get_perimeter(self):
        return 3.14*2*self.r

if __name__ == '__main__':
    r = eval(input('请输入圆的半径:'))
    #创建Circle类对象
    c = Circle(r)
    area = c.get_area()
    perimeter = c.get_perimeter()
    print('圆的面积为:{0:.2f}'.format(area))
    print('圆的周长为:{0:.2f}'.format(perimeter))

六、实战——定义学生类录入5个学生信息存储到列表中

class Student:
    def __init__(self,name,age,gender,python):
        self.name = name
        self.age = age
        self.gender = gender
        self.python = python

    #实例方法
    def info(self):
        print(self.name, self.age, self.gender, self.python)

if __name__ == '__main__':
    print('请输入五位学生的信息:(姓名#年龄#性别#成绩)')
    lst = [] # 存储五个学生对象
    for i in range(1,6):
        s = input(f'请输入第{i}位学生信息:')
        s_lst = s.split('#')
        #创建学生对象
        stu = Student(s_lst[0],s_lst[1],s_lst[2],s_lst[3])
        #将学生对象添加到列表中
        lst.append(stu)

    #遍历列表,输出学生信息
    for item in lst: #每个item都是一个学生对象
        item.info() #对象名打点调用实例方法

七、实战——实现乐器弹奏

class Instrument():
    def make_sound(self):
        pass

class Erhu(Instrument):
    def make_sound(self):
        print('二胡在弹奏')

class Piano(Instrument):
    def make_sound(self):
        print('钢琴在弹奏')

class Violin(): #默认继承object类
    def make_sound(self):
        print('小提琴在弹奏')

#编写一个演奏的函数
def play(obj):
    obj.make_sound()

if __name__ == '__main__':
    er = Erhu()
    piano = Piano()
    vio = Violin()
    play(er)
    play(piano)
    play(vio)

八、实战——描述出租车和家用轿车

#编写父类
class Car(object):
    def __init__(self,type,no):
        self.type = type
        self.no = no

    def start(self):
        print('我是车,我可以启动')
    def stop(self):
        print('我是车,我可以停止')

#出租车
class Taxi(Car):
    def __init__(self,type,no,company):
        super().__init__(type,no)
        self.company = company

    #重写父类的方法
    def start(self):
        print('乘客您好!')
        print(f'我是{self.company}出租车公司的司机,我的车牌是:{self.no},您要去哪里')

    def stop(self):
        print('目的地已到达,请您付款下车,欢迎下次乘坐')

#家用轿车
class FamilyCar(Car):
    def __init__(self,type,no,name):
        super().__init__(type,no)
        self.name = name

    #重写方法
    def start(self):
        print(f'我是{self.name},我的汽车我做主')

    def stop(self):
        print('目的地到了,我们去玩儿吧')

if __name__ == '__main__':
    taxi = Taxi('上海大众','京A88888','长城')
    taxi.start()
    taxi.stop()
    print('----------------------------------------------------')
    family_car = FamilyCar('广汽丰田','京C77777','jww')
    family_car.start()
    family_car.stop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值