类和对象

类的定义和初始化

class Animal():
    def __init__(self, name):
        self.name = name

类的继承

在子类中定义__init__方法时,父类的__init__方法会被覆盖。因此,在子类中父类的初始化方法并不会被自动调用,必须显式的调用它。

class Person(Animal):
    def __init__(self, name, type):
        super().__init__(name) # 调用父类的方法
        self.type = type

使用property对特性进行访问和设置

Python里所有的特性(attribute)都是公开的。可以创建getter和setter方法。利用属性(property),限制对特性的直接访问。

  • 通过property(getter, setter)

property的第一个参数为getter方法,第二个参数为setter方法

class Animal():
    def __init__(self, name):
        self.hiden_name = name
    def get_name(self):
        print('get my name')
        return self.hiden_name
    def set_name(self):
        print('set my name')
        return self.hiden_name
    name = property(get_name, set_name) # 把getter和setter方法定义为了name属性

当尝试访问Animal类对象的name特性时,get_name()会被自动调用。当手动赋值修改对象的name特性时,则set_name会被自动调用

animal = Animal('human')
animal.name
# get my name
# human
animal.name = 'man'
# set my name
# man
  • 通过@property@name.setter修饰符

@property用于指示getter方法 @name.setter用于指示setter方法

class Animal():
    def __init__(self, name):
        self.hiden_name = name

    @property
    def name(self):
        print('get my name')
        return self.hiden_name

    @name.setter # 如果设定的是其他属性,例如sex,则使用 @sex.setter
    def name(self, new_name):
        print('set my name')
        self.hiden_name = new_name

animal = Animal('monkey')
animal.name
# get my name

若不定义@name.setter,则name是一个只读属性

使用名称重整保护私有特性

使用_作为开头命名的方法表示它是类的内部实现

使用__作为命名的开头使其对外不可见,这种属性通过继承是无法被覆盖的

class Human():
    def __init__(self, name):
        self.__name = name

human = Human('ecmadao')
print(human.__name) # 报错
# 但也不是完全不可见
print(human._Human__name) # ecmadao

注:同时以__作为开头和结尾的变量不是私有变量,而是特殊变量,特殊变量是可以直接访问的

方法/属性的类型

  • 实例方法
  • 实例属性

self作为第一个参数的方法/属性。

  • 类方法
  • 类属性

类方法作用于整个类,对类作出的任何改变都会对它的所有实例对象产生影响。类方法的第一个参数是类本身cls,并使用前缀修饰符@classmethod

而类属性则直接写在类内部,不需要self。当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到

  • 静态方法

不会影响类也不会影响类实例的方法,具有独立性,使用前缀修饰符@staticmethod

class A():
    count = 0 # 类属性
    def __init__(self):
        A.count += 1

    @classmethod
    def kids(cls):
        print('A has', cls.count, 'objects')

    @staticmethod
    def intro():
        print('this is a example')

a1 = A()
a2 = A()
a3 = A()
A.kids()
# A has 3 objects

通过__slots__限制类实例的属性

Python作为动态语言,可以在运行的时候动态的给类的实例添加新的属性:

class Test(object):
    def __init__(self, name):
        self.name = name
test = Test('ecmadao')
test.age = 24
print(test.age) # 24

通过__slots__,则可以限制类实例所能够绑定的属性:

class Test(object):
    __slots__ = ('name', 'age')
    def __init__(self, name):
        self.name = name
test = Test('ecmadao')
test.age = 24
test.job = 'developer'
# AttributeError: 'Test' object has no attribute 'job'

results matching ""

    No results matching ""