类和对象

面向对象编程的一个重要特点就是把数据和逻辑封装起来。对象的方法函数,是与对象绑定的函数,第一个参数永远是指向自身的self,调用时不传递该参数。外部代码通过调用对象(实例)的方法函数来访问和操作数据,而不必了解内部结构和具体的操作细节。那么除了对象的方法函数,类里面还有其他类型的函数么?继续看前面定义的雇员类。

因为效益好,公司决定将员工的工资增长幅度从4%提高到6%,可以直接在类外用Employee.raiseAmount = 1.06进行调整么?可以,但是不主张。因为要尽量把对数据的操作封装在类里面。要改变的是类属性,不特属于具体的对象,所以不能用实例的方法函数。而是要用属于整个类的方法函数来调整类属性raiseAmount。

装饰器@classmethod表明是类方法函数,装饰器可以让其他函数在不需要做任何代码变动的前提下增加额外功能)。函数的第一个形参用指代类本身的cls(class),函数内部访问类属性raiseAmount时用cls.raiseAmount:

……
    @classmethod                     # 装饰器
    def set_raise_amount(cls, amount):
    # 形参amount接收传进来的工资调整幅度
        cls.raiseAmount = amount      # 对类属性raiseAmount进行赋值
……
print(Employee.raiseAmount)           # 改变之前的类属性值为1.04
Employee.set_raise_amount(1.06)       # 调用类方法函数设置属性值
print(Employee.raiseAmount)           # 改变之后的类属性值为1.06

除了实例的方法函数(第一个形参必须为指代实例的self)和类的方法函数(第一个形参必须为指代类的cls)外,类内的函数还有一种类型:静态方法函数。静态方法函数跟类有逻辑上的联系,比如在雇员Employee这个类里定义一个显示日期是星期几的函数what_day(day),星期几跟雇员的工作安排还是有关系的嘛。

类内部静态函数用装饰器@staticmethod表明身份,除此之外跟普通函数没区别,不象其它方法函数要求第一个参数必须是clsself:

@staticmethod                   # 装饰器
def what_day(day):              # 接收日期型形参
    num = day.weekday()        
    # 日期型的变量的方法函数weekday()返回星期几,
    # python所有的数据类型都是对象,都有自己的属性和方法函数(自带工具包)
    if num == 0:     # 周一
        print('\n嗨,笑一个,周一一周才一次而已! ')
    if num == 1:     # 周二
        print('\n谢天谢地,周一终于过去了,周二你好!')
    if num == 2:     # 周三
        print('\n周三是个转折点,苦尽甘要来喽!')
    if num == 3:     # 周四
        print('\n周四快乐! 小声说一句,周五近在咫尺!') 
    if num == 4:     # 周五
        print('\n周五呀,你跑哪里去啦?等你等到花儿都谢了!')
    if num == 5:     # 周六
        print('\n周六适合来点儿奇遇!')
    if num == 6:     # 周日
        print('\n在这个美好星期天……')

在类外调用类内的静态函数要what_day()要在前面加前缀Employee。实参是date类型的,所以从datetime模块引入date和timedelta,时间段要用到timedelta:

from datetime import date            # 日期类型  
from datetime import timedelta        # 时间段,即多长时间:5天,23秒
 
day = date.today()                   # 日期取今天
Employee.what_day(day)               # 调用类的静态函数,得到今天星期几
day = date.today() + timedelta(days = 4)   # 四天后的日期
Employee.what_day(day)     # 调用类的静态函数,得到四天后星期几

help(Employee)和help(employee1)都可以了解类Employee自身的以及从父类继承来的属性和方法函数:print(help(Employee)),输出结果:

class Employee(builtins.object)
 | Employee(first, surname, salary)
 |  
 | Methods defined here:                #对象的方法函数的定义在这里
 |  
 | __init__(self, first, surname, salary)
 |     Initialize self.  See help(type(self)) for accurate signature.
 |  
 | info_summary(self)
 |  
 | raise_salary(self)
 |  
 | ----------------------------------------------------------------------
 |  Class methods defined here:          # 类方法函数的定义在这里
 |  
 |  set_raise_amount(amount) from builtins.type
 |  
 | ----------------------------------------------------------------------
 | Static methods defined here:         #静态方法函数在这里
 |  
 | what_day(day)
 |  
 | ----------------------------------------------------------------------
 |  Data descriptors defined here:              # 对数据的描述在这里定义
 |  
 | __dict__
 |     dictionary for instance variables (if defined)
 |  
 | __weakref__
 |     list of weak references to the object (if defined)
 |  
 | ----------------------------------------------------------------------
 |  Data and other attributes defined here:    # 类属性
 |  
 | employeeNum = 6
 |  
 | raiseAmount = 1.04

即将推出的Python ABC教程对PythonABC视频内容进行了梳理,修正了发现的错误、对代码做了些许优化、替换掉视频中的英文注释、替换掉国内不能访问的资源……敬请关注,谢谢