python基础之封装
在类内部定义的函数无非三种用途
一:绑定到对象的方法
只要是在类内部定义的,并且没有被任何装饰器修饰过的方法,都是绑定到对象的
class Foo:
def test(self): #绑定到对象的方法
pass
def test1(): #也是绑定到对象的方法,只是对象.test1(),会把对象本身自动传给test1,因test1没有参数所以会抛出异常
pass
绑定到对象,指的是:就给对象去用,
使用方式:对象.对象的绑定方法(),不用为self传值
特性:调用时会把对象本身当做第一个参数传给对象的绑定方法
二:绑定到类的方法:classmethod
在类内部定义的,并且被装饰器@classmethod修饰过的方法,都是绑定到类的
class Foo:
def test(self): #绑定到对象的方法
pass
def test1(): #也是绑定到对象的方法,只是对象.test1(),会把对象本身自动传给test1,因test1没有参数所以会抛出异常
pass
绑定到对象,指的是:就给对象去用,
使用方式:对象.对象的绑定方法()
特性:调用时会把对象本身当做第一个参数传给对象的绑定方法
三:解除绑定的方法:staticmethod
既不与类绑定,也不与对象绑定,不与任何事物绑定
绑定的特性:自动传值(绑定到类的就是自动传类,绑定到对象的就自动传对象)
解除绑定的特性:不管是类还是对象来调用,都没有自动传值这么一说了
所以说staticmethod就是相当于一个普通的工具包
class Foo:
def test1(self):
pass
def test2():
pass
@classmethod
def test3(cls):
pass
@classmethod
def test4():
pass
@staticmethod
def test5():
pass
test1与test2都是绑定到对象方法:调用时就是操作对象本身
<function Foo.test1 at 0x0000000000D8E488>
<function Foo.test2 at 0x0000000000D8E510>
test3与test4都是绑定到类的方法:调用时就是操作类本身
<bound method Foo.test3 of <class '__main__.Foo'>>
<bound method Foo.test4 of <class '__main__.Foo'>>
test5是不与任何事物绑定的:就是一个工具包,谁来都可以用,没说专门操作谁这么一说
<function Foo.test5 at 0x0000000000D8E6A8>
四.什么是property,如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
为什么要用property:将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
封装概念:
property代码1
import math class Circle: def __init__(self,radius): #圆的半径 self.radius=radius @property #添加装饰器,area=property(area) def area(self): return math.pi * self.radius**2 #计算面积 @property #添加装饰器,perimeter=property(perimeter) def perimeter(self): return 2*math.pi*self.radius #计算周长 c=Circle(7) c.radius=10 print(c.radius) #打印出圆的半径 # print(c.area()) #会报错,TypeError: 'float' object is not callable,译为:float对象是不可调用的 # print(c.perimeter()) #float对象是不可调用的 print(c.area) #表面上是一个数据属性,但这个根本上是一个函数属性,会调用上面的area函数,打印圆的面积 print(c.perimeter) #打印圆的周长
property代码2
class People: def __init__(self,name,age,height,weight): self.name=name self.age=age self.height=height self.weight=weight @property #该装饰器可以理解为bodyindex=property(bodyindex) def bodyindex(self): #计算体脂 return self.weight/(self.height**2) p1=People('cobila',18,1.65,75) print(p1.bodyindex) #过轻:低于18.5,正常:18.5-23.9,过重:24-27,肥胖:28-32,非常肥胖, 高于32 p1.weight=200 print(p1.bodyindex)
property代码3
class People: def __init__(self,name): self.__name=name #self.__name # def tell_name(self): # return self.__name @property def name(self): return self.__name p1=People('cobila') # print(p1.tell_name()) print(p1.name) #触发name()函数的运行 # p1.name='egon' #会报错,AttributeError: can't set attribute
property代码4
class People: def __init__(self,name,SEX): self.name=name self.__sex=SEX #self.sex='male' p1.sex(相当于self.sex)='male' @property #查 def sex(self): return self.__sex #p1.__sex @sex.setter #修改 def sex(self,value): #性别是字符串类型 # print(self,value) # if not isinstance(value,str): #python没有类型限制,所以只能自己加这种类型限制 raise TypeError("性别必须是字符串类型") self.__sex=value #p1.__sex='male' @sex.deleter #删除 def sex(self): del self.__sex #触发delete函数的运行,del p1.__sex # del self.sex #这是错误的 # p1=People('cobila','male') # print(p1.sex) # p1.sex='123' # p1.sex = 'female' #这个等式触发def sex(self,value)的运行,把female这个值传给value # print(p1.sex) #输出female # p1.sex=9999999 #由于更改的不是字符串类型,所以会抛出异常 # p1=People('cobila',9999999999999999) #这里更改的是def sex(self):下面的self.__sex p1=People('cobila','male') #实例化触发__init__的运行 print(p1.sex) #输出male # del p1.sex #@sex.deleter一执行它(def sex(self)),del self.sex,无限递归,一直删除自己,会报错(RecursionError: maximum recursion depth exceeded) # print(p1.sex)
posted on 2017-04-22 02:51 bigdata_devops 阅读(370) 评论(0) 编辑 收藏 举报