类和对象

类是创建对象的模板

  • 使用class关键字创建类,命名一般按照大驼峰规则

  • object是最顶级的父类

  • 一个类可以创建多个实例对象

  • self表示实例对象本身

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class PhD(object):
    def info(self): # 定义了一个实例方法
    if self.gender == 'Male': # 通过`self`获取对象的属性
    print('He is a PhD :)')
    elif self.gender == 'Female':
    print('She is a PhD :)')

    lilei = PhD() # 实例化了一个PhD对象
    lilei.gender = 'Male'
    lilei.info() # 调用实例方法

    hanmeimei = PhD()
    hanmeimei.gender = 'Female'
    hanmeimei.info()

init魔法方法

  • 常用于属性初始化或赋值

  • 每一个类中都有__init__方法,如果没有定义,python会自动创建

  • 在实例化对象时,__init__方法会自动被调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class PhD(object):
    def __init__(self, gender):
    self.gender = gender
    self.age = 30

    def info(self): # 实例方法
    if self.gender == 'Male':
    print('He, {} years old, is a PhD :)'.format(self.age))
    elif self.gender == 'Female':
    print('She, {} years old, is a PhD :)'.format(self.age))

    lilei = PhD('Male') # 参数传递到对象的__init__方法
    lilei.info()
    lilei.address = 'Beijing' # 动态添加属性
    print(lilei.address)

    hanmeimei = PhD('Female')
    hanmeimei.info()

    print(lilei.gender, hanmeimei.gender)

私有属性和私有方法

  • 在方法和属性前加__定义

  • 只能在类的内部访问和调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class PhD(object):
    def __init__(self, name):
    self.__name = name # 定义私有属性
    def __struggle(self): # 定义私有方法
    print('{} is working on the PhD thesis...'.format(self.__name)) # 访问私有属性
    def graduate(self): # 实例方法
    self.__struggle() # 调用私有方法
    print('{} finally completed the PhD thesis :)'.format(self.__name))

    lilei = PhD('Li Lei')
    lilei.graduate()

类方法

  • 使用装饰器@classmethod装饰

  • cls表示类本身

  • 可使用类名.方法名直接调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class PhD(object):
    name = 'Li Lei' # 公有属性
    @classmethod # 装饰器
    def graduate(cls): # 参数为`cls`
    print('{} graduated eventually :)'.format(cls.name)) # 访问类属性

    print(PhD.name)
    PhD.graduate() # 不需要实例化
    hanmeimei = PhD()
    hanmeimei.name = 'Han Meimei' # 没有修改类的公有属性,只是新建了一个实例属性
    hanmeimei.graduate() # 也可以通过实例调用,仍然访问类的公有属性

类方法可用于修改类属性

1
2
3
4
5
6
7
8
9
10
11
12
13
class PhD(object):
name = 'Li Lei'
@classmethod
def get_name(cls):
print(cls.name)
@classmethod
def set_name(cls, name):
cls.name = name
print(cls.name)

PhD.get_name()
PhD.set_name('Han Meimei')
PhD.get_name()

静态方法

  • 使用装饰器staticmethod装饰

  • 不默认传入selfcls

  • 可使用类名.方法名直接调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class PhD(object):
    name = 'Li Lei'
    @staticmethod # 装饰器
    def graduate(name):
    print('{} has graduated'.format(name))

    PhD.graduate('Someone else')
    PhD.graduate(PhD.name) # 传入类的公有属性
    hanmeimei = PhD()
    hanmeimei.name = 'Han Meimei'
    hanmeimei.graduate(hanmeimei.name) # 传入实例属性

继承

  • 可以继承自一个父类,也可以继承自不同父类

  • 不同父类中如果有同名的属性和方法,调用时根据class.__mro__中的顺序调用

  • 如父类中的方法不满足需求,可以在子类中重写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class Ba(object):
    def __init__(self, name):
    self.name = name
    def struggle_1(self):
    print("{} in struggling for bachelor's degree...".format(self.name))
    def graduate(self):
    print("{} got a bachelor's degree :)".format(self.name))

    class Ms(object):
    def __init__(self, name):
    self.name = name
    def struggle_2(self):
    print("{} in struggling for a master's degree...".format(self.name))
    def graduate(self):
    print('{} graduated eventually :)'.format(self.name))

    class PhD(Ba, Ms):
    def __init__(self, name):
    self.name = name
    def phd(self):
    print('{} finally got a PhD degree :)'.format(self.name))

    lilei = Ms('Li Lei')
    lilei.struggle_2()
    lilei.graduate() # 重写父类方法

    hanmeimei = PhD('Han Meimei')
    hanmeimei.struggle_1()
    hanmeimei.struggle_2()
    print(PhD.__mro__) # 继承顺序
    hanmeimei.graduate()
    hanmeimei.phd()

多态

在不同的类中定义同名函数,从而使同名的实例方法具备不同的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Ms(object):
def __init__(self, name):
self.name = name
def is_phd(self):
return '{} has not got a PhD degree'.format(self.name)

class PhD(object):
def __init__(self, name):
self.name = name
def is_phd(self):
return '{} has got a PhD degree'.format(self.name)

def check(obj):
print(obj.name)
print(obj.is_phd())

lilei = Ms('Li Lei')
hanmeimei = PhD('Han Meimei')

check(lilei)
check(hanmeimei)