Python基础知识学习(七)——面向对象编程

685-杜同学

发表文章数:68

热门标签

首页 » Python » 正文

1.面向对象编程步骤

OOA面向对象分析

  • 分析对象的特征
  • 分析对象与对象之间的关系:聚合(如图书上需要有作者,编号等)、复合(如衣服上要有衣领,复合比聚合联系更紧密,聚合可有可没有)、依赖(如开车这个动作需要有车)
  • 分析对象间的继承关系

OOD面向对象设计

写类描述对象的模板,蓝图

OOP面向对象编程

实例化对象的过程

2.__init__()初始化函数

import datetime

class Book:
    def __init__(self, title, price, author, publisher, pubdate):
        self.title = title
        self.price = price
        self.author = author
        self.publisher = publisher
        self.pubdate = pubdate

book1 = Book("C入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
print(book1.title)

3.__repr__()交互式打印对象函数

class Book:
    def __repr__(self):
        return '<图书 {} at 0x{}>'.format(self.title, id(self))

交互模式下book1 打印成 <图书 C入门 at 0x14334523>

4.__str__()定义使用print打印内容

如未定义__str__()函数但定义了__repr__()函数,打印返回__repr__()函数的值

def __str__():
    return '[图书: {}, 定价:{}]'.format(self.title, self.price)

使用print(book1) 

返回结果 [图书:C入门,定价:29.9

5.类属性(静态属性)

当我们有一个需求是每创建一本书,都使得书的总数增加1,如果在对象实例里定义计数方法例如

import datetime

class Book:
    def __init__(self, title, price=0.0, author=None, publisher, pubdate=datrtime.date.today(), count=0):
        self.title = title
        self.price = price
        self.author = author
        self.pubdate = pubdate
        self.count = count


if __name__ == "__main__":
    book1 = Book("C入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book1.count += 1
    book2 = Book("Flask入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book2.count += 1
    book3 = Book("Pyhton入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book3.count += 1

    print("图书数量:{}".format(book3.count))

打印结果为 图书数量:1

这个时候我们发现计数这个事情,不应该依附于实例,我们可以把计数count写在类的外面,但发现这样不符合面向对象的特点,我们将count写在类里,这样就引入了类属性的概念

import datetime

class Book:
    count = 0    # count是一个类属性

    def __init__(self, title, price=0.0, author=None, publisher, pubdate=datrtime.date.today()):
        self.title = title
        self.price = price
        self.author = author
        self.pubdate = pubdate
        Book.count += 1    # 创建实例时自动图书数量+1



if __name__ == "__main__":
    book1 = Book("C入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book2 = Book("Flask入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book3 = Book("Pyhton入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))


    print("图书数量:{}".format(Book.count))     # 使用类.类属性 调用类属性

打印结果 图书数量:3

注意:python是一个松散的语言使用,实例.类属性也可以访问到类属性的值,但如果使用实例.类属性修改了类属性不会修改真正的类属性,会为实例创建一个新属性。

print('图书数量:{}'.format(Book.count))   # 图书数量:3
print('图书数量:{}'.format(book1.count))   # 图书数量:3   
book1.count = 99
print('图书数量:{}'.format(Book.count))   # 图书数量:3
print('图书数量:{}'.format(book1.count))   # 图书数量:99 

5.__del__()删除方法

假如我们删除一本图书

import datetime

class Book:
    count = 0    # count是一个类属性

    def __init__(self, title, price=0.0, author=None, publisher, pubdate=datrtime.date.today()):
        self.title = title
        self.price = price
        self.author = author
        self.pubdate = pubdate
        Book.count += 1    # 创建实例时自动图书数量+1



if __name__ == "__main__":
    book1 = Book("C入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book2 = Book("Flask入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book3 = Book("Pyhton入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))


    print("图书数量:{}".format(Book.count))     # 使用类.类属性 调用类属性

    del(book1)

    print("图书数量:{}".format(Book.count))     # 使用类.类属性 调用类属性

打印图书数量发现数量还是为3

使用__del__()方法会在实例删除时被调用

import datetime

class Book:
    count = 0    # count是一个类属性

    def __init__(self, title, price=0.0, author=None, publisher, pubdate=datrtime.date.today()):
        self.title = title
        self.price = price
        self.author = author
        self.pubdate = pubdate
        Book.count += 1    # 创建实例时自动图书数量+1
    def __del__(self):
        Book.count -= 1


if __name__ == "__main__":
    book1 = Book("C入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book2 = Book("Flask入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))
    book3 = Book("Pyhton入门", 29.9,'Tom','优品课堂', datetime.date(2016,1,3))


    print("图书数量:{}".format(Book.count))     # 使用类.类属性 调用类属性

    del(book1)

    print("图书数量:{}".format(Book.count))     # 使用类.类属性 调用类属性

打印图书数量发现数量变为2

6.类函数与静态函数

类函数(一般不用)

class Book:
    def cls_method(cls):
        print('类函数')

Book.cls_medhod(book1)  # 在调用类方法时必须给它传入一个实例对象

静态函数

class Book:
    def static_method():
        print('静态函数,逻辑上与实例无关')

Book.static_medhod()   # 只能使用类调用

加了装饰器的静态函数(一般不用)

class Book:
    @staticmethod
    def static_method():
        print('静态函数,逻辑上与实例无关')

Book.static_medhod()   # 使用类调用
book1.static_medhod()   # 使用实例调用

总结:类方法调用必须传入一个实例对象,还可以访问实例对象的属性,加了装饰器的静态方法既可以使用类调用也可以使用实例调用,没有跟普通方法区分开来一般不用。我们用处最大的就是直接用类调用的静态方法,在定义时只需要def 静态方法名()

7.@property装饰器将方法变成属性

如果我们设计一个学生类,我们最开始指定学生的年龄,但是我们使用直接指定年龄的方法过了一年之后,学生的年龄却没有发生改变,这样就不符合实际开发需求。我们,在初始化实例时不使用年龄,传入它的出生日期,再定义一个获取年龄的函数。

import datetime

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

    def get_age(self):
        return datetime.date.today().year - self.birthdate.year

if __name__ == '__main__':
    s = Student('Tom',datetime.date(1992,3,1))
    print(s.birthdate)
    print(s.get_age())

但这样我们获取名字是调用了一个方法,我们可以加@property装饰器

import datetime

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

    @property
    def age(self):
        return datetime.date.today().year - self.birthdate.year

if __name__ == '__main__':
    s = Student('Tom',datetime.date(1992,3,1))
    print(s.birthdate)
    print(s.age)    # 调用使用property装饰器定义的函数不需要加()

8.@setter设置器和@deleter删除器

使用@property修饰成属性的方法还有一个好处是可以添加设置器和删除器

import datetime

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

    @property
    def age(self):
        return datetime.date.today().year - self.birthdate.year

    @age.setter
    def age(self,value):
        raise AttributeError('禁止赋值年龄!')

    @age.deleter
    def age(self):
        raise AttributeError('年龄不能删除!')

if __name__ == '__main__':
    s = Student('Tom',datetime.date(1992,3,1))
    print(s.birthdate)
    print(s.age)    # 调用使用property装饰器定义的函数不需要加()
    s.age = 20    #报错 '禁止赋值年龄!'
    del(s.age)    #报错 '年龄不能删除!'

9.类的继承

programer继承自Emloyee类

Python基础知识学习(七)——面向对象编程

子类的初始化可以调用父类的方法,使用super().__init__()

Python可以实现多继承,所以一般使用父类方法会指定如下图,Employee.__init__(self) 注:指定使用哪个父类调用时要传入self

Python基础知识学习(七)——面向对象编程

如果一个公司有很多部门可能有需求创建一个部门类Python基础知识学习(七)——面向对象编程

这个时候员工的部门信息就不再是一个字符串,而是一个部门对象,我们为了代码可读性用department:Department标示部门应该传入部门对象,创建部门,将部门传给员工打印,打印员工的部门电话,经理。

Python基础知识学习(七)——面向对象编程

打印结果

Python基础知识学习(七)——面向对象编程

 

 

标签:

拜师教育学员文章:作者:685-杜同学, 转载或复制请以 超链接形式 并注明出处 拜师资源博客
原文地址:《Python基础知识学习(七)——面向对象编程》 发布于2019-12-29

分享到:
赞(0) 打赏

评论 抢沙发

评论前必须登录!

  注册



长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Vieu3.3主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录