17 面向对象 02
目录:
1.面向对象的小练习
2.绑定方法
3.非绑定方法
4.隐藏属性
5.property装饰器
1.面向对象的小练习
题目:
定义一个类,产生一堆对象
要求:
要有一个计数器,记录一共差生了多少个对象
class Student(): count=0 def __init__(self,name,age): self.name=name self.age=age Student.count+=1
#或者(了解)self.__class__.count+=1
obj=Student("egon",18) obj1=Student("egon1",18) obj2=Student("egon2",18) print(obj.count)
2.绑定方法
(1)、绑定给对象的方法
class Student(): school="SH" def __init__(self,name,age): self.name=name self.age=age #在类中书写方法默认绑定给对象使用的 def tell_info(self ): print("%s %s" %(self.name,self.age)) obj=Student("egon",18) obj.tell_info()
(2)、绑定给类的方法
import settings class Mysql(): school = "SH" def __init__(self,ip,port): self.ip=ip self.port=port def func(self): return Mysql(settings.ip,settings.port) obj = Mysql(settings.ip,settings.port) obj1 = obj.func() print(obj1.ip)
# application => app # Mysql ip=127.0.0.1, port:3306 => 127.0.0.1:3306 import settings class Mysql: school = 'SH' def __init__(self, ip, port): self.ip = ip self.port = port @classmethod # 意味着该方法绑定给类了,类来调用,会把类当成第一个参数传过来 def func(cls): # class_name => Mysql print(cls) return cls(settings.IP, settings.PORT) # return self.__class__(settings.IP, settings.PORT) # return Oracle(settings.IP, settings.PORT) obj = Mysql(settings.IP, settings.PORT) # obj1 = obj.func() # print(obj.ip) # print(obj.port) # obj1 = obj.func() # obj1 = obj.func(obj) # print(obj1.ip) # Mysql.func() # Mysql.func(Mysql) obj2 = obj.func()
总结:
1. 绑定给对象的
对象来调用,把对象自己当成第一个参数传递
2. 绑定给类的方法
@classmethod
类来调用,把类名当成第一个参数传递
3.非绑定方法(不需要传参数)
既不绑定给对象,也不绑定给类
class Test(): def __init__(self,name,age): self.name=name self.age=age self.id=self.create_id() @staticmethod #静态方法 def create_id(): import uuid return uuid.uuid4() obj=Test("egon",18) print(obj.id) #用类调用 print(Test.create_id()) #用对象调用 print(obj.create_id())
4.隐藏属性
(1)如何隐藏属性
# class Student(): # __school = 'SH' # _Student__school # # def func(self): # print('func') # # # stu = Student() # print(stu.school) # print(stu.__school) # print(Student.__dict__) # print(Student._Student__school) # 修改 # Student._Student__school = 'bj' # print(Student._Student__school)
(2)为何要隐藏属性:
对内部的属性或者方法做隐藏,可以更好的限制外部使用者, 要想让外部访问,在类内部定义对外可访问的接口。
class Student(): __school = 'SH' # _Student__school # school = 'SH' # _Student__school def __init__(self, name): self.__name = name # self._Student__name def __func(self): # _Student__func print('func') def get_school(self): return self.__school # self._Student__school def set_school(self, v): if type(v) is not str: return self.__school = v def get_func(self): return self.__func() # print(Student.__dict__) # Student._Student__func(11) obj = Student('egon') # obj.set_school('z') obj.set_school(123) print(obj._Student__school)
隐藏属性的特点:
1.在类定义阶段发生了变形_类名__属性名(_Student__school)
2.对外不对内(只要隐藏了外部拿不到,内部可以拿到)
3.如果外部想要调用隐藏函数,在类内部可以开放可访问的接口(函数),目的是可以更好的限制外部的调用
5.property装饰器
# class Student(): # __school = 'SH' # _Student__school # __name = 'egon' # def __init__(self, name): # self.__name = name # self._Student__name # # def __func(self): # _Student__func # print('func') # # # @property # 这个函数已经变成了属性 # # def get_name(self): # # return self.__name # self._Student__school\ # # @property # 这个函数已经变成了属性 # def name(self): # return self.__name # self._Student__school # # @name.setter # def name(self, v): # self.__name = v # # @name.deleter # def name(self): # print("不让删除") # # # obj = Student('egon') # print(obj.get_name) # obj.set_name('xyz') # print(obj.name) # # obj.name = 'xyz' # print(obj.name) # del obj.name class Student(): __name = 'egon' def get_name(self): return self.__name # self._Student__school def set_name(self, v): self.__name = v def del222_name(self): print("不让删除") # property中的参数必须按照这个顺序 xxxx = property(get_name,set_name,del222_name) obj = Student() print(obj.xxxx) obj.xxxx = 'x' print(obj.xxxx)