面向对象编程
OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
类和实例
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同
访问限制
要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
继承和多态
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
获取对象信息
1.基本类型都可以用type()判断:type(123)
2.如果一个变量指向函数或者类,也可以用type()判断
3.对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数:isinstance(h, Dog)
4.获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list
实例属性和类属性
1.实例属性属于各个实例所有,互不干扰;
2.类属性属于类所有,所有实例共享一个属性;
3.不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
__slots__
Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
class Student(object):
__slots__ = ('name', 'age')
__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
@property
Python内置的@property装饰器就是负责把一个方法变成属性调用的
MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系
class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
pass
定制类 __xxx__
如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
Enum可以把一组相关常量定义在一个class中,且class不可变,而且成员可以直接比较
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
type()函数可以查看一个类型或变量的类型;
metaclass,直译为元类,先定义metaclass,就可以创建类,最后创建实例。
OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
类和实例
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同
访问限制
要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
继承和多态
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
获取对象信息
1.基本类型都可以用type()判断:type(123)
2.如果一个变量指向函数或者类,也可以用type()判断
3.对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数:isinstance(h, Dog)
4.获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list
实例属性和类属性
1.实例属性属于各个实例所有,互不干扰;
2.类属性属于类所有,所有实例共享一个属性;
3.不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
__slots__
Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
class Student(object):
__slots__ = ('name', 'age')
__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
@property
Python内置的@property装饰器就是负责把一个方法变成属性调用的
MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系
class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
pass
定制类 __xxx__
如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
Enum可以把一组相关常量定义在一个class中,且class不可变,而且成员可以直接比较
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
type()函数可以查看一个类型或变量的类型;
metaclass,直译为元类,先定义metaclass,就可以创建类,最后创建实例。