廖雪峰Python教程阅读笔记——6. 面向对象编程

6.面向对象编程

OOP是一种设计思想,OOP把对象作为程序的基元。一个对象包括属性和操作属性的方法。
在Python中,所有的对象都可视为对象,当然也可以自定义对象。自定义的对象数据类型,就是面向对象中的类(class)。
设想打印学生的成绩,学生有姓名和成绩两种属性。我们创建一个学生对象Student,有姓名name和成绩score两个属性。如果要打印学生的成绩,必须创建出一个学生对象出来,然后使用print_score,让对象把自己的数据打印出来。

'测试学生对象'
class Student(self, name, score):
    '学生类'
    def __init__(self):
        '初始化对象,类似于构造函数'
        self.name = name
        self.score = score

    def print_score(self):
        '打印输出'
        print("%s, %s" % (self.name, self.score))

6.1类和实例

面向对象的最重要的概念就是类(class)和实例(instance)。在Python中用关键字class紧跟类名,来定义类。定义好了类,可以使用类名+()来实例化:

>>>bart = Student('Minie',69)

该语句,是创建一个student对象,并将变量bart指向该对象。
注意到,上面定义的类,__init__方法第一个参数是self,表示创建实例本身。有了__init__方法,实例化对象时,就不能不传参数了,必须传入与__init__方法匹配的参数。类似于java的构造函数。
和普通函数相比,在类中定义的函数,第一个参数永远是实例变量self,并且调用时,不需要传该参数。除此之外,类的方法和普通函数没有区别。
- 数据封装
如上述的例子,student对象,在类中,定义了一些数据姓名name和分数score。这些数据的函数是和student类本身关联起来的。

小结:类是创建实例的模板,而实例是一个一个的具体的对象,各个实例拥有的数据都互相独立。方法就是与实例绑定的函数,与普通函数不同,方法可以直接操作类中的数据。

6.2访问限制

在class内部,可以有属性和方法,而外部代码可以直接调用实例来操作数据。但是从前面定义的Student类来看,外部代码还是可以自由的修改实例的name、score属性:

>>>bart = Student('Bartun',90)
>>>bart.score
90
>>>bart.score=80
>>>bart.score
80

如果要让内部属性不被外部改变,则把属性前面加两个_,在Python中,实例的变量如果用__开头,就变成了一个私有变量,只有内部可以访问,外部不能访问。
我们把Student类改造一下:

class Student(object):
    def __init__(self,name,score):
        self.__name = name
        self.__score = score
    def print_score(self):
        print('%s: %s' % (self.__name,self.__score))

此时,无法通过外部访问内部变量__name__score。如果想要访问,就必须加getset方法

注意:在Python中,变量名类似__XXX__开头和结尾都是__的,说明是特殊变量。特殊变量时可以直接访问的,不是Private的。有时候类似_xxx这种变量,这种变量虽然可以被直接访问,但是按照约定的规则,视此类型的变量为私有变量,不要随意访问。

6.3继承和多态

在OOP程序中,我们定义了一个类(class),该类可以被继承。
定义一个Animal类,有run()方法和eat()方法,再定义一个cat和dog类,也有run方法。当子类和父类都有相同的方法时,子类方法覆盖掉父类方法,这种现象称为多态。
在继承关系中,子类的数据类型是属于父类的数据类型。

动态语言 VS 静态语言
对于类的继承,如果是静态语言(Java),继承时传入的类型必须是父类型或者其子类。否则无法调用run()方法。
对于Python类型,不一定是父类型,只要保证传入的类型中有run()方法就行。这就是Python的”file-like object”鸭子类型。

小结:
继承可以把父类的所有功能继承下来,也可以重载。动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。

6.4获取对象信息

当我们拿到一个对象的引用时,如何知道这个对象是什么类型,有哪些方法?

  • 获取类型type()
    通过type()可以获取对象的类型:
>>> type(123)
<class 'int'>
>>> type('ab')
<class 'str'>
>>> import math                                      
>>> type(abs)     ##获取函数的类型
<class 'builtin_function_or_method'>

可以通过是否相等,判断两个对象的类型是否一致,如果对于继承关系的对象,最好用isinstance()函数。
- 获取方法dir()
如果要获取一个对象的所有属性和方法,可以使用dir()函数。它返回一个包含所有字符串的list。

>>> dir('abc')                                                                                                                              
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getit
em__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul
__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subc
lasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isal
num', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'lj
ust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitl
ines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']                                                           

其中,不乏有__XXX__的属性和方法,这在Python中是有特殊用途的,比如__len__方法返回长度。在Python中,你调用了len()函数,会返回一个对象的长度。实际上,在lne()内部,它会自动调用该对象的__len__方法。
下面代码是等价的:

>>> len('abc')                                        
3                                                   
>>> 'abc'.__len__()                                                   
3 

剩下的都是普通属性和方法。
再配合getattr()setattr()hasattr()可以直接操作一个对象的状态。

小结:
通过一系列内置函数,我们可以对任意一个对象进行剖析,但是只有在不知道对象信息的时候,我们才会获取对象信息。

6.5实例属性和类属性

略.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值