Python基础知识学习-第8天

16-面向对象编程OOP 02

1 假如要统计实例化的对象的个数,应该将统计变量放入类名下面,而不是__init__()的下面。跟具体对象关联的成员放在__init__()下面,否则放在类名下面。

class Book():
    count = 0

    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1

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

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

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    print('图书数量:{}'.format(Book.count))
>>>图书数量:3

当删除某个对象时,怎样将统计变量减一:

class Book():
    count = 0

    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1

    def __del__(self):
        Book.count -= 1

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

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

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    del(book3)
    print('图书数量:{}'.format(Book.count))
>>>图书数量:2

如果定义了一个属于类的成员而不是属于实例的成员,既可以通过类名来调用,也可以通过实例名来调用:

class Book():
    count = 0

    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1

    # def __del__(self):
    #     Book.count -= 1

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

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

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    # del(book3)
    print('图书数量:{}'.format(book2.count))
>>>图书数量:3

就是说,此时的局部成员就相当于全局成员。但若是修改局部成员的值的话,两者就没了关系,全局成员的值不会改变。

class Book():
    count = 0

    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1

    # def __del__(self):
    #     Book.count -= 1

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

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

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    # del(book3)
    print('图书数量:{}'.format(Book.count))
    print('图书数量:{}'.format(book2.count))
    book2.count = 99
    print('图书数量:{}'.format(Book.count))
    print('图书数量:{}'.format(book2.count))
>>>图书数量:3
>>>图书数量:3
>>>图书数量:3
>>>图书数量:99

2 静态函数。与实例无关,无法通过实例调用。

class Book():
    count = 0

    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1

    # def __del__(self):
    #     Book.count -= 1

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

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

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

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    # del(book3)
    # print('图书数量:{}'.format(Book.count))
    # print('图书数量:{}'.format(book2.count))
    # book2.count = 99
    # print('图书数量:{}'.format(Book.count))
    # print('图书数量:{}'.format(book2.count))
    Book.static_method()
>>>静态函数,逻辑上与实例无关

如果希望能通过实例调用,可在static_method前面加上一个@staticmethod:

class Book():
    count = 0
    
    # 初始化时调用
    def __init__(self, title, price = 0.0, author = None):
        self.title = title
        self.price = price
        self.author = author
        Book.count += 1
    
    # 删除时调用
    # def __del__(self):
    #     Book.count -= 1

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

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

    @staticmethod # 注意中间没有下划线
    def static_method(): # 注意没有self
        print('静态函数,逻辑上与实例无关')

    def print_info(self):
        print(self.title, self.price, self.author)

if __name__ == '__main__':
    book1 = Book('Python', 29.9, 'peter')
    book2 = Book('flask')
    book3 = Book('asp.net')
    # del(book3)
    # print('图书数量:{}'.format(Book.count))
    # print('图书数量:{}'.format(book2.count))
    # book2.count = 99
    # print('图书数量:{}'.format(Book.count))
    # print('图书数量:{}'.format(book2.count))
    book2.static_method()
>>>静态函数,逻辑上与实例无关

3 设计一个学生录入系统,要求录入名字,年龄:

import datetime
class student:

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

    # 使用@property后就将方法变成了属性
    @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(1994, 1, 20))
    print('名字:{}'.format(s.name))
    print('年龄:{}'.format(s.age))
>>>名字:Tom
>>>年龄:26

尝试删除年龄:

if __name__ == '__main__':
    s = student('Tom', datetime.date(1994, 1, 20))
    # print('名字:{}'.format(s.name))
    # print('年龄:{}'.format(s.age))
    del(s.age)
>>>AttributeError: 禁止删除年龄

尝试赋值年龄:

if __name__ == '__main__':
    s = student('Tom', datetime.date(1994, 1, 20))
    # print('名字:{}'.format(s.name))
    # print('年龄:{}'.format(s.age))
    s.age = 18
>>>AttributeError: 禁止赋值年龄

尝试通过修改出生日期改变年龄:

if __name__ == '__main__':
    s = student('Tom', datetime.date(1994, 1, 20))
    # print('名字:{}'.format(s.name))
    # print('年龄:{}'.format(s.age))
    s.birthdate = datetime.date(2004, 1, 20)
    print('年龄:{}'.format(s.age))
>>>年龄:16

说明通过修改出生日期来修改年龄是可行的,但是不能直接修改年龄。

17-面向对象编程OOP 03

1 设计一个公司员工管理系统:

import datetime

class Employee():
    def __init__(self, department, name, birthdate, salary):
        self.department = department
        self.name = name
        self.birthdate = birthdate
        self.salary = salary

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

    def give_raise(self, percent, bonus = 0):
        self.salary = self.salary * (1 + percent + bonus)

    def __repr__(self):
        return '员工:{}'.format(self.name)

    def working(self):
        print('员工:{}在工作...'.format(self.name))

# 继承时,派生类的类名写在class后面,基类的类名写在括号里
class Programer(Employee):
    def __init__(self, department, name, birthdate, salary, speciality, project):
        # 表示Programer类的department, name, birthdate, salary直接继承自基类
        super().__init__(department, name, birthdate, salary)
        self.speciality = speciality
        self.project = project

    def working(self):
        print('程序员:{}在开发{}项目'.format(self.name, self.project))

if __name__ == '__main__':
    p = Programer('开发部', 'peter', datetime.date(1994, 1, 20), 8000, 'Python', 'CRM')
    print(p)
    print('程序员{}的部门是:{}'.format(p.name, p.department))
    print('程序员{}的工资是:{}'.format(p.name, p.salary))
    p.give_raise(0.1, 0.1)
    print('程序员{}涨工资后的工资是:{}'.format(p.name, p.salary))
    p.working()
    print(p.age)
>>>员工:peter
>>>程序员peter的部门是:开发部
>>>程序员peter的工资是:8000
>>>程序员peter涨工资后的工资是:9600.000000000002
>>>程序员:peter在开发CRM项目
>>>26

再增加一个HR的派生类,并修改一下:

import datetime

class Department():
    def __init__(self, department, phone, manager):
        self.department = department
        self.phone = phone
        self.manager = manager

class Employee():
    def __init__(self, department:Department, name, birthdate, salary):
        self.department = department
        self.name = name
        self.birthdate = birthdate
        self.salary = salary

    def __repr__(self):
        return '<部门:{}>'.format(self.department)

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

    def give_raise(self, percent, bonus = 0):
        self.salary = self.salary * (1 + percent + bonus)

    def __repr__(self):
        return '员工:{}'.format(self.name)

    def working(self):
        print('员工:{}在工作...'.format(self.name))

# 继承时,派生类的类名写在class后面,基类的类名写在括号里
class Programer(Employee):
    def __init__(self, department, name, birthdate, salary, speciality, project):
        # 表示Programer类的department, name, birthdate, salary直接继承自基类
        super().__init__(department, name, birthdate, salary)
        self.speciality = speciality
        self.project = project

    def working(self):
        print('程序员:{}在开发{}项目'.format(self.name, self.project))

class HR(Employee):
    def __init__(self, department, name, birthdate, salary, qualification_level = 1):
        # 此处使用Employee()而不是super()是因为当多继承时,即有多个父类时,会出现混淆
        Employee().__init__(department, name, birthdate, salary)
        self.qualification_level = qualification_level

    def working(self):
        print('人事:{}正在面试新员工'.format(self.name))

if __name__ == '__main__':
    # p = Programer('开发部', 'peter', datetime.date(1994, 1, 20), 8000, 'Python', 'CRM')
    # print(p)
    # print('程序员{}的部门是:{}'.format(p.name, p.department))
    # print('程序员{}的工资是:{}'.format(p.name, p.salary))
    # p.give_raise(0.1, 0.1)
    # print('程序员{}涨工资后的工资是:{}'.format(p.name, p.salary))
    # p.working()
    # print(p.age)
    dep = Department('技术部', '010-12345678', '张三')
    p = Programer(dep, 'marry', datetime.date(1995, 1, 20), 9000, 'C++', 'CMR')
    p.give_raise(0.2, 0.1)
    print('程序员{}的工资是{}元'.format(p.name, p.salary))
    print(p.department)
>>>程序员marry的工资是11700.0>>><__main__.Department object at 0x00000079D9F2BCF8>
发布了23 篇原创文章 · 获赞 0 · 访问量 413

猜你喜欢

转载自blog.csdn.net/Mr_Wang0120/article/details/104179054