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>