面向对象编程-进阶(python3入门)
一、property装饰器的使用
#property:将一个方法伪装成一个数据属性 #如果不用property装饰器的话,这个bmi值就需要用 obj.bmi() 来调取数值,这个看起来更像一个功能,而不像一个特征 #例1 # class People: # def __init__(self,name,height,weight): # self.name = name # self.height =height # self.weight = weight # # @property # def bmi(self): # return self.weight / (self.height ** 2) # # obj = People('egon',1.8,70) # print(obj.bmi) #例2 如果不使用property装饰器,则取到name 需要使用obj.name() 这看起来更像一个函数 #推荐使用这种方法 # class People: # def __init__(self,name): # self.__name = name # # @property #访问某个属性的操作 # def name(self): # return self.__name # # @name.setter #但凡被property装饰过的函数,才会出现.setter,该装饰器是用来 修改函数的值 # def name(self,value): # if type(value) is not str: # print('必须是字符串类型') # return # self.__name = value # # @name.deleter #删除某一个属性 # def name(self): # print('不可删除') # # obj = People('lich') # # print(obj.name) # print(obj.__dict__) # # obj.name = 'egon' # print(obj.__dict__) # # print(obj.name) # # print(obj.__dict__) # # # # # # del obj.name #例3 property的古老使用方法(不推荐使用) class People: def __init__(self,name): self.__name = name def get_name(self): return self.__name def set_name(self,value): if type(value) is not str: print('必须str') return self.__name = value def del_name(self): del self.__name name = property(get_name,set_name,del_name) obj = People('lich') print(obj.name) obj.name = 'egon' print(obj.__dict__) del obj.name print(obj.__dict__)
二、绑定方法和非绑定方法
格式及使用场景和方法:
''' 绑定方法: 特殊之处:绑定给谁就应该由谁来调用,会将调用者(点左边的就是调用者)当作第一个参数自动传入 绑定对象的方法:类中定义的函数在没有被任何装饰器装饰的情况下,默认就是绑定给对象的 绑定对象的方法应该由对象来调用,自动传入的是对象 绑定类的方法:为类中定义的函数添加装饰器classmethod 绑定类的方法应该由类来调用,自动传入的是类 非绑定方法 特殊之处:无论类和对象谁来调用,都只是一个普通函数,没有自动传值的效果。 ''' #example 1: # class People: # def __init__(self,name,age): # self.name = name # self.age = age # # # def tell_info(self): # print('<%s:%s>'%(self.name,self.age)) # # # @classmethod #类来调用,会自动传入类,若对象来调用的话,仍然传入类 # def func1(cls): # print(cls) # # # @staticmethod # def func2(a,b): # print('==========>',a,b) # # # print(People.func1) # obj = People('egon',19) # # print(obj.func1) # obj.func1() # # obj.func2('obj1','obj2') # People.func2('people1','people2') # # print(obj.func2) #只是普通函数 # print(People.func2) #只是普通函数 # example 2: import setting #见下面的setting代码段 class MySQL: def __init__(self,ip,port): self.id = self.create_id() self.ip = ip self.port = port def tell_info(self): print('<%s:%s,%s>'%(self.ip,self.port,self.create_id())) @classmethod def from_config(cls): return cls(setting.IP,setting.PORT) @staticmethod def create_id(): import uuid return uuid.uuid4() obj = MySQL.from_config() print(obj.__dict__) obj.tell_info()
IP = '1.1.1.1' PORT = 3306
三、反射
#反射:用字符串来操作对象或者类的属性 #场景:从文件/其他地方传来的值,这些值为字符串,且需要通过这些字符串来访问属性 class Foo: x = 1 def __init__(self,m,n): self.m = m self.n = n def func(self): print('<%s:%s>'%(self.m,self.n)) #hasattr #判断一个对象是否有这个属性 print(hasattr(Foo,'x')) #True, 本质'x' in Foo.__dict__ print('='*40) #getattr print(getattr(Foo,'x')) # Foo.__dict__['x'] #得到数据属性 res_func = getattr(Foo,'func') #得到函数属性 print(res_func) print('='*40) #setattr #Foo.__dict__['x] = 1111111 setattr(Foo,'x','1111111') #修改x的值 print(Foo.x) setattr(Foo,'y',2222) print(Foo.y) res = setattr(Foo,'z',None) #value可以设定为默认值 print(res) print('='*40) #delattr delattr(Foo,'x') print(Foo.__dict__) print(hasattr(Foo,'x'))
四、内置方法
#如何使自定义对象在打印时,得到有效的一些数据 #__str__(该方法必须返回字符串类型)在被打印时自动触发,然后将该方法的返回值当作结果输出 # class People: # def __init__(self,name,age): # self.name = name # self.age = age # # def __str__(self): # # print('+++++++++>run') # return '<%s:%s>'%(self.name,self.age) # # # # obj = People('ccc',19) # # # print(list) # print(People) # # l = list([1,2,3,]) #对象,是一个列表 # print(l) #打印列表对象,展现了内容(内置打印的更好看) # print(obj) #打印自定义数据类型对象(打印了一个内存地址)###其实就在打印obj.__str__() #如何使自定义对象在打印时,得到有效的一些数据 #__del__()会在对象被删除时 自动触发,或者当程序结束时也会自动触发,我们可以在__del__内做一些回收资源的事情 # class Foo: # def __init__(self,x,y,file): # self.x = x # self.y =y # self.f = open(file,mode='rt',encoding='utf-8') # # def __del__(self): # # 回收系统资源 # self.f.close() # # obj1 = Foo(10,20,'setting.py') # print(obj1.__dict__) # # del obj1 # print('===============>') #isinstance(obj,cls) 和 issubclass(sub,super) # class Foo(object): # pass # # obj = Foo() # print(isinstance(obj,Foo)) #True,判断obj是不是Foo的实例 # class Foo(object): # pass # # class Bar(Foo): # pass # # print(issubclass(Bar,Foo)) #判断Bar是不是Foo的子类 print(type([1,2,3,4] is list)) #以前都在用type来判断。。。 print(isinstance([1,2,3,4],list)) #推荐使用这种方法来判断数据类型