参考廖雪峰大神的python3.0教程,适用于有一定基础的Java程序员,会对比着Java来学习python。代码在PyCharm中运行通过,地址为github。本篇主要介绍python面向对象编程相关的知识,在上一篇介绍了python的一些基础知识,包括安装运行、基础语法、函数、高级特性、函数式编程、模块等。
面向对象编程
类和对象
- 定义类语法:class ClassName(superClass/object),其中括号里为父类,没有的话写object
- 类中定义的函数第一个参数永远是实例变量self,调用时,不用传递该参数。
- 允许对实例动态增加变量和方法,类的不同实例拥有的变量和方法可能不同
- 允许对类动态添加方法,添加后对象都能访问
- 类动态添加属性限制slots:定义一个特殊的slots变量,来限制该class实例能动态添加的属性。仅对当前类实例起作用,子类不起作用
访问限制
私有变量(private):两个下划线开头xxx,跟java一样可以有set和get方法。区别于两个下划线开头和结尾的特殊变量xxx__
继承和多态
- 与java相同点:继承父类的所有功能,支持方法覆盖
- 与java不同点:
- Python动态语言–Java静态语言。下例:只需要保证传入的对象有一个run()方法就可以了,不需要是Animal类
- Python支持多重继承,可以同时继承多个类。而Java的继承extends只能去继承一个类12345678910111213141516171819202122232425# 父类-动物class Animal(object):def run(self):print('Animal is running...')# 父类-尖叫class MixlnBark(object):def bark(self):print("Barking....");# 方法:依赖于run方法def run_twice(animal):animal.run()animal.run()# 多重继承示例class Dog(Animal,MixlnBark):def run(self):print("Dog is Running");dog = Dog();dog.run()dog.bark()# 动态语言示例class Timer(object):def run(self):print('Start...')run_twice(Dog())run_twice(Timer())
获取对象信息
- type(对象):获取类型
- isinstance(判断的实例,类型1,类型2…):判断实例是否是这几种类型
- dir(对象):获取对象所有属性和方法。配合以下方法,直接操作一个对象的状态,通常先通过has判断对象有没有该方法,有的话执行:
- hasattr(对象,’属性名/方法名’)
- getattr(对象,’属性名/方法名’)
- setattr(对象,’属性名/方法名’,set值)123456789import types# typeprint(type(abs)==types.BuiltinFunctionType)# isinstanceprint(isinstance('a', str))print(isinstance([1, 2, 3], (list, tuple)))# dirprint(dir('abc'))print(hasattr('abc', '__init__'))
类属性和实例属性
类属性就类似于java中的类的静态属性,static
面向对象高级编程
检查参数与@property
定制类
xxx前后两个下划线的函数帮助定制类,重写这些方法之后,可以实现一些功能。
- str:类似于java的toString()
- getattr:获取属性,可以用于防止没有此属性,也可以用于链式调用
call:相当于直接运行一个对象,不需要方法,这个方法相当于默认方法。
12345678910111213141516171819202122232425262728293031323334class Student(object):def __init__(self, name):self.name = namedef __str__(self):return 'Student object (name: %s)' % self.namedef __getattr__(self, attr):if attr == 'score':return 99elif attr == 'age':return lambda: 25else:raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)def __call__(self):print('My name is %s.' % self.name)stu = Student('Michael')print(stu)print(stu.score)print(stu.age)# print(stu.phone)print(stu())callable(stu)# __getattr__应用:链式调用class Chain(object):def __init__(self, path=''):self._path = pathdef __getattr__(self, path):return Chain('%s/%s' % (self._path, path))def __str__(self):return self._pathprint(Chain().status.user.timeline.list)iter
如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个iter()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环- getitem
要表现得像list那样按照下标取出元素,需要实现getitem()方法1234567891011121314151617181920212223242526272829303132333435363738# __iter__和__next__:将斐波那契数列改成可以for循环的形式# __getitem__:使其实现取元素的功能class Fib(object):def __init__(self):self.a, self.b = 0, 1 # 初始化两个计数器a,bdef __iter__(self):return self # 实例本身就是迭代对象,故返回自己def __next__(self):self.a, self.b = self.b, self.a + self.b # 计算下一个值if self.a > 100: # 退出循环的条件raise StopIteration();return self.a # 返回下一个值def __getitem__(self, n):if isinstance(n, int): # n是索引a, b = 1, 1for x in range(n):a, b = b, a + breturn aif isinstance(n, slice): # n是切片start = n.startstop = n.stopif start is None:start = 0a, b = 1, 1L = []for x in range(stop):if x >= start:L.append(a)a, b = b, a + breturn Lfor n in Fib():print(n)f = Fib()print(f[3])print(f[:5])
枚举类
Enum可以把一组相关常量定义在一个class中,且class不可变
元类
参考
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
http://blog.csdn.net/pipisorry/article/details/39909057