面向对象
面向对象编程(oop)是一种程序设计思想。在面向对象编程中,对象时程序的基本单元。在Python中,所有数据类型都可以视为对象,自定义对象数据类型就是面向对象中的类(class)的概念。
比如:
class Student(object):
def __init__(self,name,score):
self.name=name
self.score=score
def print_score(self):
print('name:%s,score:%d'%(self.name,self.score))
以上就是一个类的定义,Student
是一个抽象的数据类型,执行S1=Student('lama',12)
则S1
是类的实例,也就是对象。
面向对象编程的三大特点是:
* 封装,继承 多态*
类和实例
Instance(实例)就是类(class)的具体化,比如a=10 a就是实例,类是int
类的定义:
关键字class
开头,后面紧跟类名,类名通常为大写字母开头,紧接着是(object)
,表示该类从哪个类继承。如果没有,则都写object
,这是所有类都要继承的类。如下:
class Student(object):
pass
创建实例:
创建实例通过类名()
实现的。如下:
S1=Student()
注意:Python中类和C++中不一样的是,在Python中可以随意给实例绑定属性。
比如上例中,我们给S1添加city
属性
>>> S1.city='nantong'
>>> S1
<__main__.Student object at 0x000001D08D424B00>
>>> S1.city
'nantong'
由此可以看到,本来类中是没有该属性的,但是通过实例,可以给该实例绑定一个对象。
特殊方法__init__(self,...)
由于类起到模板的作用,所以在创建实例时,我们可以把必须绑定的属性强制添加进去,通过定义特殊的方法(函数)__init__
__init__
第一个参数永远是self
表示实例本身,创建实例时,必须传入和__init__
方法匹配的参数,self不需要。注意,该方法在创建实例时,自动调用。
数据封装
作用:在外部如果需要访问实例内部的属性参数,则可以用实例名.属性名
来访问和修改,而这样的结果就是,实例内的数据并不安全,我们需要使用类的方法(函数)来访问这些属性参数,实现封装。
方法:虽然可以通过方法访问实例的属性,但是依然可以在外部访问实例属性,所以采用将属性名称前加上两个下划线,变为一个私有属性(private)。只有内部可以访问,外部不可以访问。代码实例如下:
class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def Get_Name(self):
return self.__name
def Get_Score(self):
return self.__score
执行结果如下:
>>> S1=Student('lama',22)
>>> S1.name
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
S1.name
AttributeError: 'Student' object has no attribute 'name'
>>> S1.__name
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
S1.__name
AttributeError: 'Student' object has no attribute '__name'
>>> S1.Get_Name
<bound method Student.Get_Name of <__main__.Student object at 0x000001E4CCC1A400>>
>>> S1.Get_Name()
'lama'
所以外部就访问不了私有属性了。
注意:在Python中 _xxx_的变量,是特殊变量,特殊变量可以访问,不是private变量。但是其实只是私有变量名被解释器改变了,我们可以使用dir(实例名)
先获取改变的属性名,再访问。比如:
class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def Get_Name(self):
return self.__name
定义了两个私有属性,__name
和__score
,我们执行如下:
>>> S1=Student('lama',99)
>>> dir(S1)
['_Student__name', '_Student__score', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> S1._Student__name
'lama'
你看,我们可以访问私有属性了,更改试试,:
S1._Student__name='LAMA'
>>> S1.Get_Name()
'LAMA'
可以看到,私有成员确实被改变了。