现在的位置: 主页 > 公司荣誉 > 文章列表

Python学习笔记——面向对象编程

作者:昆明飞华工贸有限公司 来源:www.kmfhgm.com    未知发布时间:2017-09-11 13:51:22
Python学习笔记——面向对象编程

定义类使用class关键字,后面紧跟类名(首字母大写),接着是从哪个类继承下来的(所有类最终会继承object)。

通过类名加参数就可以创建实例。可以自由的给实例绑定属性。可以把一些必须绑定的属性写在类中,通过__init__方法在初始化时将属性值进行绑定。

类中的函数与普通函数的区别是第一个参数是self,表示创建的实例本身(在调用时不需要传,Python解释器自己会把实例变量传进去)。

class Person(object): def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print("Hello, my name is %s and I'm %s years old" % (self.name, self.age)) tom = Person('tom', 20) tom.say_hello() # Hello, my name is tom and I'm 20 years old 2. 访问限制

如果要让类的内部属性不被外部访问,可以在前面加上两个_,就变成了私有变量。

如果外部要访问/修改变量,可以加上get_xxx、set_xxx这样的方法。

前后都有两个_的是特殊变量,可以直接访问。

开头有一个_的变量是“约定俗成”的私有变量,外部可以访问,但是不要这么做。

开头有两个_的变量其实也是可以访问的,假设类名是Person,变量名是__name,在目前版本的Python中,外部可以通过_Person__name来访问__name变量。但是不建议这么做,除了规范外,不同版本的Python解释器会把__name改成不同的变量名。

3. 继承和多态

object是根(基类),任何类都可以追溯到object。

多态的含义(假设有一个类Animal,里面有一个run方法):

对于一个变量,我们只需要知道它是Animal类型,无需确切知道它的子类型,就可以调用run()方法,而具体调用的run()方法是作用在Animal、Dog还是Cat对象上,由运行时刻该对象的确切类型决定。即调用方只管调用,不管细节,当新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是开闭原则:

对扩展开放:允许新增Animal的子类;

对修改封闭:不需要修改依赖Animal类型的函数。

对于静态语言(如Java),如果需要传入Animal类型,则传入的对象必须是Animal类型或它的子类;而对于Python这种动态语言,不一定需要传入Animal类型,只需要保证传入的对象有一个run()方法就可以了。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

Python支持多重继承,常使用MixIn的设计模式。举个例子,Python自带了TCPServer和UDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixIn和ThreadingMixIn提供。通过组合,我们就可以创造出合适的服务来。

4. 获取对象信息

type()函数可以获取对象的类型。

对于有继承关系的class来说,可以使用isinstance()函数。该函数判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。

ininstance()还支持判断一个变量是否是某些类型中的一种:

isinstance([1, 2, 3], (list, tuple))

dir()用于获取一个对象的所有属性和方法,它返回一个包含字符串的list。

方法也是属性,如果想知道哪些是方法,可以再使用callable()进行判断。

getattr()、setattr()和hasattr()用于操作对象的属性和函数,如:

# obj对象是否有属性x hasattr(obj, 'x') # 设置一个属性y setattr(obj, 'y', 20) # 获取属性y getattr(obj, 'y') # 获取属性z(如果试图获取不存在的属性,会有错误,因此可以给一个默认值) getattr(obj, 'z', 404) 5. 实例属性和类属性

给实例绑定属性的方法是通过实例变量,或者通过self变量。

而如果想给类本身绑定一个属性,可以直接在class中定义属性。

类属性实例也可以使用,不过前提是实例没有这个属性。

个人认为比较好的方式是实例属性和类属性不要使用相同的名字,另外在获取类属性的时候,通过类名来获取,而不是通过实例名来获取。

6. 使用@propery

@property装饰器可以将一个方法变为属性调用。

把一个getter方法变成属性赋值,只需要加上一个@property就可以了。这时@property本身又创建了另一个装饰器@xxx.setter,其中xxx是属性名,负责把一个setter方法变成属性赋值。

还可以只定义getter方法,这样这个属性就是一个只读属性。

class Student(object): @property def birth(self): return self._birth @birth.setter def birth(self, value): self._birth = value @property def age(self): return 2016 - self._birth s = Student() s.birth = 1990 s.birth s.age 7. 定制类

Python的class中有许多形如__xxx__这样有特殊用途的函数,可以帮助我们定制类。

__len__

定义了__len__()方法的class,可以直接作用于len()函数,即len()函数内部调用了对象的__len__()方法。

__slots__

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:武汉网页设计 https://www.feimao666.com

上一篇:百度算法频繁更新 SEO职场更需正能量 下一篇:最后一页