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