Python学习----面向对象编程
2015-09-07 23:08
405 查看
面向对象编程
注意到
有了
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量
和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
三、继承和多态
运行结果:
当我们传入
当我们传入
对于静态语言(例如Java)来说,如果需要传入
对于Python这样的动态语言来说,则不一定需要传入
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个
object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
注意:在编写程序的时候,千万不要把实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
一、类和实例
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把
name,
score等属性绑上去:
class Student(object): def __init__(self, name, score): self.name = name self.score = score
注意到
__init__方法的第一个参数永远是
self,表示创建的实例本身,因此,在
__init__方法内部,就可以把各种属性绑定到
self,因为
self就指向创建的实例本身。
有了
__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与
__init__方法匹配的参数,但
self不需要传,Python解释器自己会把实例变量传进去:
>>> jack = Student('Jack', 89) >>> jack.name 'Jack' >>>jack.score 89
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量
self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
>>> jack = Student('Jack', 59) >>> alex = Student('Alex', 87) >>> jack.age = 8 >>> jack.age 8 >>> alex.age Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'age'
三、继承和多态
class Animal(object): def run(self): print('Animal is running...')
class Dog(Animal): def run(self): print('Dog is running...')
dog = Dog() dog.run()
运行结果:
Dog is running...
def run_twice(animal): animal.run() animal.run()
当我们传入
Animal的实例时,
run_twice()就打印出:
>>> run_twice(Animal()) Animal is running... Animal is running...
当我们传入
Dog的实例时,
run_twice()就打印出:
>>> run_twice(Dog()) Dog is running... Dog is running...
静态语言 vs 动态语言
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是
Animal类型或者它的子类,否则,将无法调用
run()方法。
对于Python这样的动态语言来说,则不一定需要传入
Animal类型。我们只需要保证传入的对象有一个
run()方法就可以了:
>>> class Like(object): ... def run(self): ... print('Like running...') ... >>> run_twice(Like()) Like running... Like running...
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个
read()方法,返回其内容。但是,许多对象,只要有
read()方法,都被视为“file-like
object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了
read()方法的对象。
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
五、实例属性和类属性
当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。来测试一下:>>> class Student(object): ... name = 'Student' ... >>> s = Student() # 创建实例s >>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性 Student >>> print(Student.name) # 打印类的name属性 Student >>> s.name = 'Michael' # 给实例绑定name属性 >>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性 Michael >>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问 Student >>> del s.name # 如果删除实例的name属性 >>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了 Student
注意:在编写程序的时候,千万不要把实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
相关文章推荐
- Python 读取csv的某行
- Python 读取csv的某列
- Python 根据索引提取列表的一部分
- 《机器学习实战》笔记之五——Logistic回归
- Python打开文件时的几种模式比较
- Python iter
- 快速排序Python实现
- Windows下安装Python3的numpy、matplotlib、scipy包
- python 字典访问的三种方法
- 《笨方法学python-6》之lambda
- “Python"学习笔记(五)(控制流)
- NumPy教程(转)
- wxpython初学者(三) 之flexgirdsizer,TextEntryDialog,SingleChoiceDialog
- python的urllib2包基本使用方法
- wxpython初学者(三)
- “Python"学习笔记(四)(函数二)
- 2 Dimension list (list中的list)game 2048 part2
- Python之面向对象初体验
- python会什么比c慢
- Python 之 Post 登陆 Dz 论坛