Python学习总结(四):面向对象编程,转换思维

        从这节开始,我们将要接触编程思想——面向对象编程,很重要!!!学过C或者Java都知道,不管是面向过程还是面向对象,想要彻底掌握,必须理解这种程序设计思想,这样才能熟练的编程,而不是盲目的死记硬背,重要的是编程思想,其他的都是思想演变而来,正所谓:知其然知其所以然。下面来说画下重点:

     (1)类和实例

        类(Class)是抽象出来的模板,实例(Instance)是根据类创建出来的具体对象。打个比方:汽车是类,而奥迪就是实例,是汽车的一个具体对象,它包含汽车的所有特征,不同的汽车只是数据参数不同而已。

# 类
class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score
        print('the isinstance %s:%s' % (self.__name, self.__score))
    
    def print_score(self):
        print('%s:%s' % (self.__name,  self.__score))

if __name__ == '__main__':
    A = Student('Ada', 89)  # 对象A
    B = Student('Bob', 56)  # 对象B
    A.print_score()
输出:
the isinstance Ada:89
the isinstance Bob:56
Ada:89

        上面是类的基本定义格式,object是继承的父类,如无特定继承的类,则这是所有类最终都会继承的类。__init__()是一个初始化方法,是个特殊的方法,第一个参数是self,实例化时不必传对应参数,表示创建的实例本身,在方法中加入了一个打印,是为了方便理解,print_score()是一个自定义的方法,根据输出内容可以看出:实例化的过程就是__init__()的一种隐式调用,将参数传给了self。

     (2)三大特性:封装、继承、多态

封装:直接在类的内部定义访问数据的方法,通过对象直接或者self间接获取被封装的内容; 继承:子继承父的内容,被继承的class称为基类、父类或超类; 多态:可对不同类的对象使用同样的操作;
# 类-继承和多态
class Animal(object):
    def run(self):
        print('Animal is running...')


class Cat(Animal):
    def run(self):
        print('Cat is running...')


class Dog(Animal):
    def run(self):
        print('Dog is running...')

    def eat(self):
        print('Dog is eating...')

if __name__ == '__main__':
    cat = Cat()
    cat.run()

         从代码中可以看出:Cat和Dog类都继承了Animal类,同样也就继承了父类的方法run(),这里Cat和Dog类中都重新构造了run()方法,若不重新构造则直接调用父类的run(),而在Dog类中新增了新的方法eat(),也可以看出,子类在继承父类的方法的同时,也能增加自己的一些方法。另外,python是一种多态语言,崇尚鸭子类型,关于它的概念这里不做叙述,可自行百度

     (3)面向对象高级编程

        Python内置的@property装饰器就是负责把一个方法变成属性调用的,在我们定义数据库字段类的时候,往往需要对其中的类属性做一些限制,一般用get和set方法来写,那在python中,我们该怎么做能够少写代码,又能优雅的实现想要的限制,减少错误的发生呢,这时候就需要我们的@property:

class Student(object):
    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0~100!')
        self._score = value


if __name__ == '__main__':
    k = Student()
    k.score = 99
    print(k.score)

        上面的代码,把get方法变为属性只需要加上@property装饰器即可,此时@property本身又会创建另外一个装饰器@score.setter,负责把set方法变成给属性赋值,这么做完后,我们调用起来既可控又方便。

        Python允许使用多重继承,通过多重继承,一个子类就可以同时获得多个父类的所有功能,MixIn就是一种常见的设计。

class Person(object):
    pass

class Student(Person):
    pass

class Teacher(Person):
    pass

class SkillMixin(object):
    pass

class BasketballMixin(SkillMixin):
    def skill(self):
        return 'basketball'

class FootballMixin(SkillMixin):
    def skill(self):
        return 'football'

class BStudent(Student, BasketballMixin):
    pass

class FTeacher(Teacher, FootballMixin):
    pass

s = BStudent()
print(s.skill())

t = FTeacher()
print(t.skill())

         定制类、枚举类、元类的使用,更加丰富了程序开发,这里不再详述,有兴趣的可以百度查看具体的用法:

# 定制类、枚举类、元类(metaclass)

from enum import Enum, unique


class Student(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'Student object (name:%s)' % self.name
    __repr__ = __str__


Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
             'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

# metaclass是类的模板,所以必须从`type`类型派生:


class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)


class MyList(list, metaclass=ListMetaclass):
    pass


@unique
class Weekday(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

if __name__ == '__main__':
    print(Student('Ada'))
    for name, member in Month.__members__.items():
        # value属性则是自动赋给成员的int常量,默认从1开始计数
        print(name, '=>', member, ',', member.value) 
    L = MyList()
    L.add(1)
    print(L)

        写的不是很全,但对于面向对象编程来说要掌握的基本也就这些了。

文章来源:

Author:海岸线的曙光
link:https://my.oschina.net/u/3747963/blog/1612369