栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

类--python基础

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

类--python基础

1. 类 1.1 面向对象

面向过程的关注点:怎么做
面向对象的关注点:谁来做
面向对象编程(00P)是一种解决软件复用的设计和编程方法。这种方法把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的形式的描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。
类:类是具有一组相同或相似特征(属性)和行为的一系列对象的组合;是模板,模板中可以包含多个函数,函数里实现一些功能;类是负责创建对象的
对象:则是根据模板创建的实例,通过实例对象可以执行类中的函数。
类相当于制造汽车的图纸,用这个图纸制造的汽车相当于对象。

# 1. 面向对象编程介绍
# 问题情景;每位同学报告,并做自我介绍
stu_a = {
    'name': 'zhangsan',
    'age': 18,
    'gender': 'F',
    'hometown': 'henan'
}

stu_b = {
    'name': 'lisi',
    'age': 19,
    'gender': 'M',
    'hometown': 'hubei'
}

stu_c = {
    'name': 'wangwu',
    'age': 16,
    'gender': 'M',
    'hometown': 'qinghai'
}


def stu_info(stu):
    '''
每位学生自我介绍:
    '''
    for key, value in stu.items():
        print('我的', key, '是', value)


stu_info(stu_a)
stu_info(stu_b)
stu_info(stu_c)

'''
上述情景花费大量时间在学生信息定义上,自我介绍使用函数进行了封装简化, 
'''
class Student:
    def __init__(self,name,age,birthplace):
        self.name = name
        self.age = age
        self.birthplace = birthplace
        print('我叫{},今年{}岁,家在{}'.format(self.name,self.age,self.birthplace))
stuA = Student('张三',20,'河南')
stuB = Student('李四',24,'湖北')


使用类能够实现代码的重复利用,提高开发效率

1.2 类的组成

类由3部分构成:
类的名称:类名
类的属性:一组数据,反应特征
类的方法:行为

2. 类的创建
# 创建类
class Human:  # 1. 类名: 采用“大驼峰”命名方法:(1)每个单词首字母大写,(2)单词与单词之间没有下划线
   # 2. 特征
    name = '小小'   # 类属性,定义在类里面,方法外面的属性称为类属性
    age  = 20
    # 3. 方法(类中的方法称为实例方法)
    def eat(self):  # self是名字标识,可以是其他的名字
        print('大口吃...')
    def walk(self):
        print('散步中...')

# 创建对象:类的一个实例化
wm = Human()
wm.eat()  # 调用方法
print(wm.age)   # 调用属性

此时,不论创建的对象是谁,调用属性时输出属性名字将都为小小,年纪20岁。不能实现根据对象不同给与不同的属性
下面先来了解self参数

2.1 利用self在类中封装的方法中输出对象属性

self和对象指向同一个内存地址,可以认为self就是实例对象的引用

# 创建类
class Cat:  
    def eat(self):
        print('Tom大口吃...')
    def walk(self):
        print('Tom散步中...')

# 增加属性的方法1:对对象通过=赋值语句增加:不推荐使用

Tom = Cat()
Tom.eat()
Tom.walk()
print('*'*10)
Penny = Cat()
Penny.eat()
Penny.walk()


此时在方法中输出的对象是固定的,不论是Tom对象还是Penny对象都只能输出Tom的名字,这明显不是我想要的结果,
想要将不同对象的名字输出到控制台就需要使用self参数。




可以发现,哪一个对象调用方法,self就是哪一个对象的引用,指向的是同一个内存地址。
在方法内部访问方法的属性,可以使用self.属性名。

2.2 类中的初始化方法:init

当使用类名()创建对象时,会自动执行以下操作:
1.为对象在内存中分配空间–创建对象
2. 为对象的属性设置初始值–初始化方法(init)
以下面的代码为例:
(1)首先找有没有一块空间是Cat
(2) 找到Cat类后,向内存中申请一块空间
(3) 去Cat中找有没有__init__方法,如果没有则执行将开辟的内存给对象Tom;如果有__init__方法,则会进入__init__方法执行里面的动作,然后将内存地址给对象Tom

# 创建类
class Cat:  # 1. 类名: 采用“大驼峰”命名方法,每个单词首字母大写
# 哪一个对象调用的代码,self就是哪一个对象的引用
    def eat(self):
        print('%s大口吃...'% self.name)
    def walk(self):
        print('%s散步中...'% self.name)

# 增加属性的方法1:对对象通过=赋值语句增加:不推荐使用
print(id(Cat))
Tom = Cat()
print(id(Tom))

class Cat:
    def __init__(self):
        print('测试不执行能输出本句话吗')
    def eat(self):
        print('我不爱吃老鼠')

Tom = Cat()

可以看出__init__方法中的内容在创建对象Tom时自动进行了输出,不需要主动调用,而eat方法中的内容则需要主动调用才可以输出

2.3 在初始化方法内部定义属性

当希望创建出的类默认拥有某些属性,可以在__init__方法中使用self.属性名=属性的初始值进行定义

class Cat:
    def __init__(self):
        self.name='Tom'
        print(self.name)
    def eat(self):
        print('我不爱吃老鼠')

Tom = Cat()
Tom.eat()
print(Tom.name)


但是将属性值设置为固定值,在创建对象的时候会有不便,比如

此时创建的对象为Penny,但是输出仍未Tom的固定字符;想要实现不同对象不同的属性值,可以在__init__初始化方法中接收参数

2.4 定制变量输出信息:str

在python中,使用print函数输出对象变量,默认会输出这个变量的引用对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)

若在开发中,希望在使用print输出时不是看到对象所属的类与内存地址,可以使用__str__方法自定义输出内容,但是需要注意:__str__方法必须返回一个字符串(return函数)

class Cat:
    def __init__(self,name):
        self.name=name
        print(self.name)
    def __str__(self):
        return '这是一个Cat类'
    def eat(self):
        print('%s我不爱吃老鼠'%self.name)

Penny=Cat('Penny')
print(Penny)
Penny.eat()

3. 封装
class Human:
    def __init__(self,name,weight):
        self.name=name
        self.weight=weight
    def __str__(self):
        return (self.name+'  原本  '+str(self.weight)+'kg  的体重变化情况:')
    def run(self,times):
        self.weight = self.weight-0.5*times
        print(times,'次跑步后的体重为:', self.weight)
    def eat(self,times):
        self.weight = self.weight+0.5*times
        print(times,'次吃饭后的体重为:', self.weight)
xm = Human('xiaoming',50)
print(xm)
xm.run(2)
xm.eat(1)
xm.run(1)

class Item:
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        return (self.name + ', 占地面积是:  ' + str(self.area) + ' 平方米')


bed = Item('席梦思', 4)

chest = Item('衣柜', 2)

table = Item('餐桌', 150)


class House:
    def __init__(self,house_type,area):
        self.house_type = house_type
        self.area = area
        self.free_area = area
        self.item_list = []
    def __str__(self):
        # python能够自动将一对括号内部的代码连接在一起
        return ('户型:%s;  总面积:%.2f' %(self.house_type,self.area))
    def add_item(self,item):
        if item.area>self.free_area:
            print(' %s  太大了,放不下'%(item.name))
        else:
            self.item_list.append(item.name)
            self.free_area = self.free_area-item.area
            print('家里面有:%s,剩余面积为:%.2f 平方米' % (self.item_list,self.free_area))

my_home = House('两室一厅',70)
print(my_home)

my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)


在python中如果不知道给对象设置什么属性值,可以设置将属性值设置为None

4. 继承

继承是实现代码的重用,相同的代码不需要重复编写
子类拥有父类的所有属性和方法

# 继承
# 定义动物类:有吃、喝、跑、睡
class Animal:
    def eat(self):
        print('吃...')
    def drink(self):
        print('喝...')
    def run(self):
        print('跑...')
    def sleep(self):
        print('睡...')

# 再定义1个动物类中的狗类,除了拥有吃、喝、跑、睡、还有吠
class Dog:
    def eat(self):
        print('吃...')
    def drink(self):
        print('喝...')
    def run(self):
        print('跑...')
    def sleep(self):
        print('睡...')
    def bark(self):
        print('汪...')

使用继承就不需要在狗类中重新编写或赋值与动物类中相同的方法;且在父类方法中改变的属性和方法能够同步到子类中。

# 继承
# 定义动物类:有吃、喝、跑、睡
class Animal:
    def eat(self):
        print('吃...')
    def drink(self):
        print('喝...')
    def run(self):
        print('跑...')
    def sleep(self):
        print('睡...')

# 再定义1个动物类中的狗类,除了拥有吃、喝、跑、睡、还有吠
class Dog(Animal):
    def bark(self):
        print('汪...')
wangcai = Dog()
wangcai.drink()


修改动物类(Animal)中的方法drink,可以看到子类的Dog()对象,在调用drink方法时也同步发生了变化

4.1 继承的传递性

C类从B类继承,B类又从A类继承,那么C类就具有B类和A类的所有属性和方法

class Animal:
    def eat(self):
        print('吃...')
    def drink(self):
        print('喝喝喝喝喝')
    def run(self):
        print('跑...')
    def sleep(self):
        print('睡...')

# 再定义1个动物类中的狗类,除了拥有吃、喝、跑、睡、还有吠
class Dog(Animal):
    def bark(self):
        print('汪...')

class KeJi(Dog):
    def jump(self):
        print('蹦...')

wangcai = KeJi()
wangcai.drink()
wangcai.bark()
wangcai.jump()

4.2 重写父类方法 4.2.1 覆盖父类的方法

在开发中,父类的方法实现和子类的方法实现不同,可以使用覆盖的方式,在子类中重新编写父类的方法实现
具体实现方式:在子类中定义一个和父类同名的方法并且实现
重写之后,子类的对象只会调用子类中重写的方法,而不再调用同名的父类封装方法
如:柯基类的叫声与狗类不一样,可以通过柯基类中重新定义bark方法实现

4.2.2 对父类方法扩展

如果父类中封装的方法只是子类方法的一部分,可以使用扩展的方式在子类中重写父类的方法
实现方式:
使用super().父类方法,来调用父类方法
编写子类特有的方法
比如:KeJi类中bark方法,除了会Dog类中的叫法,还会其他叫法,就可以使用super().父类方法实现父类方法的继承,同时再加上KeJi类的独特叫法

4.3 多继承

子类可以有多个父类,并且具有所有父类的属性和方法

class 子类名(父类名1,,父类名2,...)
     pass
class A:
    def test(self):
        print('这是父类A')
class B:
    def demo(self):
        print('这是父类B')
class D(A,B):
    pass
d = D()
d.demo()
d.test()


如果不同的父类存在同名的方法或属性,应尽量避免使用多继承。
python中不同父类存在同名的方法或属性时,子类的继承顺序,可以通过类的内置属性MRO(method resolution order)方法查看

按照MRO输出结果从左至右的顺序查找,如果找到方法就直接执行,不再搜索;没找到,继续向后一个类中搜索,直至最后一个,仍没有则报错

5. 多态

多态是不同的子类独享调用相同的父类方法,会产生不同的执行结果
(1) 多态可以增加代码的灵活度
(2) 以继承和重写父类方法为前提
(3) 是调用方法的技巧,不会影响类的内部设计

class Dog:
    def __init__(self,name):
        self.name = name
    def game(self):
        print(self.name,'正在玩耍...')
class KeJi(Dog):
    def game(self):
        print(self.name,'花式玩耍中...')
class Human:
    def __init__(self,name):
        self.name = name
    def play_with(self,so):
        print(self.name,'正和',so.name,'玩耍')
        so.game()

wangcai1  = Dog('旺财')
xiaomei = Human('小美')
xiaomei.play_with(wangcai1)

wangcai2 = KeJi('短腿旺财')
xiaomei.play_with(wangcai2)


可以看到在play_with方法中,传入不同类的对象,导致不同的执行效果
(1)在python中每一个对象都有自己独立的内存空间,保存各自不同的属性
(2)多个对象的方法,在内存中只有1份,保存在类所在的内存空间,在调用方法时,需要把对象的引用传递到方法内部
(3) 类对象在内存中只有1份,使用一个类可以创建出多个对象

参考资料: 黑马程序员Python教程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/942540.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号