在Python中想定义一个类是比较简单的,好比要定义一个Person类,以下代码便可:微信
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): pass p1 = Person()
固然咱们也能够给类添加相应的属性,好比Person的姓名,年龄,性别等,而且在new一个Person对象后能够对这些属性进行修改,以下代码所示:spa
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.age = age #年龄 self.sex = sex #性别 def __str__(self): #定义直接打印Person对象,输出的内容。至关于Java中的toString()方法 return ('%s , %s , %s ' % (self.name, self.age, self.sex)) p1 = Person('Demon', 18, 'M') print(p1) #Demon , 18 , M p1.age = 28 #修改对象的年龄 print(p1) #Demon , 28 , M
Python是面向对象的语言,咱们都知道面向对象的三大特色:继承、封装和多态。而在上面的代码中,咱们能够轻易地经过person. 调用属性来访问和修改值,这明显不符合面向对象中封装的思想。好比对于Person类中的年龄属性,可能比较私人,因此咱们不但愿能够任意的访问和修改它的值。在Java中,咱们是经过private关键字来装饰属性私有,那么在Python中有没有相似的关键字呢?显然是有的,在Python中采起在变量名前加__(两个下划线)的方式来将属性私有。以下代码所示:对象
# -*- coding: utf-8 -*- # __author : Demon # date : 1/5/18 8:24 PM class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年龄,将年龄私有 self.sex = sex #性别 def __str__(self): #定义直接打印Person对象,输出的内容。至关于Java中的toString()方法 return ('%s , %s , %s ' % (self.name, self.__age, self.sex)) p1 = Person('Demon', 18, 'M') print(p1) #Demon , 18 , M p1.age = 28 #这里只是给p1对象动态的增长了一个age属性 print(p1) #Demon , 18 , M print(p1.age) #28
初看上面的代码,彷佛感受并无达到私有的目的,由于咱们经过p1.age仍是成功地进行了赋值,程序并无报错。其实这里是由于Python能够动态地给对象增长属性和方法,这句话至关于动态地给p1这个对象增长了一个age属性。因此在咱们作了赋值操做以后,咱们再次打印p1,age的值依然是18。说明咱们确实已经将类里的age属性进行的私有。同理方法的私有也是同样的处理。继承
在Python中,有几种方式来定义变量:utf-8
一、以单划线开头:这种类型的变量能够经过对象.调用,可是它表示的意思是我能够调用,但请把我视为是私有的。并且若是是经过from xxx_module import *是没法访问的,可是若是是import xxx_module的方式,则能够访问到,类对象和子类也均可以访问。get
二、仅以双划线开头:这种类型的变量就是私有。可是它能够经过__类名__变量名来访问,但强烈建议不要这样作it
三、以双划线开头,并以它结尾:这种类型的变量在Python中一般都表示具备特殊意义的变量,好比__init__,__str__等。因此咱们在定义变量时不要这样定义class
四、仅以单划线结尾:这种类型的变量是用于避免与Python关键字进行冲突所采起的一种解决办法import
以下图演示访问权限效果:变量
上面的介绍了,经过加双划线开头的方式实现了变量和方法。参照在学Java时的思路,若是想要访问私有变量,咱们会给变量添加get和set方法。一样咱们在Python中也是同样的处理,代码以下所示:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年龄,将年龄私有 self.sex = sex #性别 def getAge(self): return self.__age def setAge(self, age): self.__age = age p1 = Person('Demon', 18, 'M') print(p1.getAge()) #18 p1.setAge(28) print(p1.getAge()) #28
可是这样看着彷佛不是很方便,每次都要调用一个方法。有没有可能像以前同样调用p1. age = 28就能直接赋值呢?显然在Python中是能够的,这就要用到property。
property的定义:
使用代码示例:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年龄,将年龄私有 self.sex = sex #性别 def getAge(self): return self.__age def setAge(self, age): self.__age = age age = property(getAge, setAge, 'This is age property') p1 = Person('Demon', 18, 'M') print(p1.age) #18 p1.age = 28 print(p1.age) #28
说明:
1. property接受四个参数,分别是get, set, del, doc,前三个参数分别对应get方法,set方法,del方法,顺序不能出错。最后一个参数是doc,至关于对方法进行说明。
2. property返回一个property属性,返回值的变量名与最终对象. 后面的名称是一致的
观察上面的代码,咱们仍然须要多写一行property的代码,而Python其实提供了一个更方便的实现方式来达到上述要求,即便用@property。说明以下:
示例代码以下:
class Person(object): def __init__(self, name, age, sex): self.name = name #姓名 self.__age = age #年龄,将年龄私有 self.sex = sex #性别 @property def age(self): #注意方法名直接为变量名 return self.__age @age.setter #注意方法名直接为变量名 def age(self, age): self.__age = age p1 = Person('Demon', 18, 'M') print(p1.age) #18 p1.age = 28 print(p1.age) #28
说明:
1. @property至关于对age方法进行了一个装饰,它使得咱们能经过对象.方法名来调用对应的属性
2. @property所装饰的方法名与对象 . 调用的名称要保持一致
3. @property会生成另外的装饰器,@方法名.setter, @方法名.getter, @方法名.deleter,分别对应set, get, del方法。这里get方法用得不多,由于已经经过@property直接对应到了get方法
微信搜索【帕森与加瓦】可关注公众号