Python3学习笔记——类
#!/usr/bin/env python #-*- coding:utf-8 -*- #面向对象(类+对象) 三大特性:封装、继承、多态 类的成员: 字段: 普通字段:保存在对象(实例)中,执行只能通过对象访问 静态字段:保存在类中,执行时可以通过对象访问,也可以通过类访问 方法: 普通方法:保存在类中,由对象调用 静态方法:@staticmethod,保存在类中,通过类可以直接调用,且不需要self参数 类方法:@classmethod,保存在类中,由类直接调用,需要一个cls参数,代指当前类 类的创建和使用: class 类名: def 方法名(self,参数): print("hello") 实例名=类名() 实例名.方法名(参数) # 1.类的定义: class Bar: #叫Bar的类 def foo(self): #叫foo的方法 print('hello') # 2.类的执行 obj = Bar() #创建实例(对象)--执行方法的中间人 obj.foo() # # 3.self参数 类在创建的过程中会在内存中开辟一个属于类的空间,当创建一个实例的时候也会创建属于实例的空间, 当实例需要执行类中的方法,回去找类空间相应的方法,方法中的self参数,接收的就是实例本身。 所以self代指调用方法的对象(实例) 例1: class Bar: def foo(self,arg): print(self,arg) obj = Bar() print(obj) obj.foo('hello') <__main__.Bar object at 0x000001D1995E4470> <__main__.Bar object at 0x000001D1995E4470> hello 例2: class Bar: def foo(self,arg): print(self,self.name,arg) #②self表示实例本身,self.name:从方法中读取实例中的元素, obj = Bar() obj.name = "Tom" #①在实例的内存空间中添加新的元素 obj.foo('hello') <__main__.Bar object at 0x000001EB3F6645F8> Tom hello # 4.构造方法 obj = Bar() #作用:1.创建对象;2.通过对象执行类中的一个特殊方法 例1: class Bar: def __init__(self): """ 构造方法 """ print('创建对象时自动执行构造方法') obj = Bar() 例2: class Bar: def __init__(self,name,age): self.n = name self.a = age def foo(self): print(self.n,self.a) obj = Bar("Tom",10) obj.foo() # 5.类的三大特性之“继承” 5.1:父类与子类 class Father: #父类(基类) def __init__(self): pass def bar(self): pass class Son(Father): #子类(派生类) def foo(self): pass obj = Son() obj.bar() 5.2:类的重写 class F: def f1(self): print('F.f1') def f2(self): print('F.f2') class S(F): def s1(self): print('S.s1') def f2(self): #重写父类方法,其本质是在执行f2的方法时,在S类中已经找到,不会再向上(即父类)去找 print('S.f2') obj = S() obj.f2() 5.3:supper(子类名,self).父类方法 父类名.父类方法(self) class F: def f1(self): print('F.f1') def f2(self): print('F.f2') class S(F): def s1(self): print('S.s1') def f2(self): super(S,self).f2() #先执行父类的方法,再执行自己的方法 F.f2(self) # 另一种写法,推荐使用supper写法 print('S.f2') obj = S() obj.f2() 5.4:多继承 ①左侧优先 ②一条道做到黑 ③有共同的父类,最后在父类中找 例1: class F: def bar(self): print('F.bar') class F1(F): def boo(self): print('F1.bar') class F2: def bar(self): print('F2.bar') class S(F1,F2): #从下往上找 pass obj = S() obj.bar() --------- F.bar 例2: class F1: def bar(self): print('F1.bar') class F2: def bar(self): print('F2.bar') class S(F2,F1): #从左往右找 pass obj = S() obj.bar() --------- F2.bar 例3: class Base: def bar(self): print('Base.bar') class F(Base): def foo(self): print('F.bar') class F1(F): def foo(self): print('F1.bar') class F2(Base): def bar(self): print('F2.bar') class S(F1,F2): pass obj = S() obj.bar() #有共同的父类,最后在父类中找 --------- F2.bar # 6.类的三大特性之多态 Python原生多态。 # 7.类的成员之字段 class Bar: #静态字段:属于类, city = "Beijing" def __init__(self,name): #普通字段:属于对象,只能通过对象(实例)访问 self.name = name #普通方法 def foo(self): print(self.name) obj = Bar('Tom') #通过对象访问普通字段 print(obj.name) #直接通过类访问静态字段 print(Bar.city) ------- Tom Beijing # 8.类的成员之方法 class Bar: # 普通方法 def foo(self): print("Bar.foo") # 静态方法 @staticmethod def show(): # print("Bar.show") # 静态方法 @staticmethod def person(name,age): print(name,age) # 类方法 @classmethod def classmd(cls): # cls是类名, print('Bar.classmd') print(cls) # 普通方法,通过对象调用 obj = Bar() obj.foo() # 静态方法,通过类可以直接调用 Bar.show() Bar.person('Tom',18) # 类方法,通过类可以直接调用 Bar.classmd() --------- Bar.show Tom 18 Bar.classmd <class '__main__.Bar'> # 应用场景: # 对象中需要保存一些值,执行某功能的时候需要使用对象中的值 --> 普通方法 # 不需要对象中的值 --> 静态方法 # 9.类的成员之属性 class Bar: def __init__(self): pass # 属性 @property def foo(self): return 1 @foo.setter def foo(self,val): print(val,"setter") @foo.deleter def foo(self): print("delete") obj = Bar() obj.foo=123 #执行赋值语句将执行@foo.setter下对应的方法 del obj.foo #执行@foo.deleter下对应的方法 ---------- 123 setter delete 例1: class Page: def __init__(self,page): try: p = int(page) except Exception as e: p = 1 self.page = p @property def start(self): val = (self.page-1) * 10 return val @property def end(self): val = self.page * 10 return val li = [] for i in range(1000): li.append(i) while True: p = input("请输入页码:") if p == "q": break obj = Page(p) print(li[obj.start:obj.end]) 例2:属性的另一种表示方法 class Bar: def f1(self): return 1 def f2(self,val): print('f2:',val) def f3(self): print("f3:del") per = property(fget=f1,fset=f2,fdel=f3,doc="注释") obj = Bar() print(obj.per) obj.per = 123 del obj.per ---------- 1 f2: 123 f3:del # 10.成员修饰符 ***子类在继承父类时,父类中的私有字段子类不能继承*** 例:公有成员和私有成员 #!/usr/bin/env python # -*- coding: utf-8 -*- class Bar: __city = "Beijing" #静态字段的私有化 def __init__(self,name,age): self.name = name self.__age = age #私有字段,外部不能直接访问 def foo(self): #方法可以访问私有字段,通过方法间接访问私有字段 print(self.__age) def __show(self): # 私有方法,外部不能直接访问 return "hello world" def func(self): #间接访问私有方法 return self.__show() obj = Bar('Tom',18) print(obj.name) obj.foo() # 通过方法间接访问私有字段 #间接访问私有方法 r = obj.func() print (r) # 11.特殊成员 11.1 __call__方法 class Bar: def __init__(self): print("init") def __call__(self): print("call") obj = Bar() obj() #对象加括号自动执行__call__方法 11.2 __str__ 与 __int__ class Bar: def __init__(self): pass def __int__(self): return 111 def __str__(self): return "str" obj = Bar() print(obj,type(obj)) r = int(obj) #int 加对象,自动执行对象的int方法,并将返回值赋值给int对象 print(r) r = str(obj) print(r) #str 加对象,自动执行对象的str方法,并将返回值赋值给str对象 ------------ str <class '__main__.Bar'> 111 str 11.3 例:__str_ class Bar: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return "%s:%s" %(self.name,self.age) obj = Bar("Tom",18) print(obj) ----------- Tom:18 11.4 __del__ 析构方法:对象销毁的时候执行 class Bar: def __init__(self): pass def __del__(self): print("析构方法") obj = Bar() 11.5 __dict__ 将字段中的成员以字段的形式返回 class Bar: """注释""" def __init__(self,name,age): self.name = name self.age = age obj = Bar('Tom',18) #将字段中的成员以字段的形式返回 print(Bar.__dict__) print(obj.__dict__) --------- {'__module__': '__main__', '__init__': <function Bar.__init__ at 0x0000013DAD733AE8>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': '注释', '__dict__': <attribute '__dict__' of 'Bar' objects>} {'name': 'Tom', 'age': 18} 11.6 __getitem__ 、 __setitem__ 和 __delitem__ class Bar: """注释""" def __init__(self): pass def __getitem__(self,item): return item + 10 def __setitem__(self,k,v): print(k,v) def __delitem__(self,val): print('delete:',val) obj = Bar() print(obj[2]) obj['name']='Tom' del obj['del'] ---------------- 12 name Tom delete: del 11.7 __iter__ 如果类中有__iter__方法,其对象就是一个可迭代对象; 对象名.__iter__()的返回值是迭代器 class Bar: def __iter__(self): return iter([11,22,33]) obj = Bar() for i in obj: print(i) #for循环执行obj对象的类中的__iter__方法,并获取其迭代器;循环上一步中返回的对象 # 12.mateclass # 13.反射 #通过字符串操作对象中的成员 class Bar: def __init__(self,name,age): self.name = name self.age = age def foo(self): print("hello world") obj = Bar("Tom",18) b = "name" #利用b取出obj中name的值 # 方法1: print(obj.__dict__[b]) # 方法2: # getattr() 去什么东西里面获取什么内容 s = getattr(obj,b) print(s) f = getattr(obj,'foo') print(f) f() #getattr 判断是否有某个成员 print(hasattr(obj,'foo')) #setattr setattr(obj,'k1','v1') #新设置的值存在对象中 print(obj.k1) #delattr delattr(obj,'name') print(obj.name) # 从类中取成员 class Bar: city = "Beijing" def __init__(self,name,age): self.name = name self.age = age def foo(self): print("hello world") print(getattr(Bar,'city')) # 从模块中取成员 import module getattr(module,'func') getattr(module,'Bar') # 例:反射的应用 #!/usr/bin/env python # -*- coding: utf-8 -*- while True: inp = input("请输入要访问的URL:") if inp == "q": break class Bar: def f1(self): return "首页" def f2(self): return "新闻" def f3(self): return "博客" obj = Bar() if hasattr(obj,inp): f = getattr(obj,inp) print(f()) else: print("404") # 14.单例模式 应用场景:数据库连接池 例: class Bar: __v = None @classmethod def get_instance(cls): if cls.__v: return cls.__v else: cls.__v = Bar() return cls.__v # 不用再使用Bar()创建实例 obj1 = Bar.get_instance() print(obj1) obj2 = Bar.get_instance() print(obj2) obj3 = Bar.get_instance() print(obj3) ---------------- <__main__.Bar object at 0x0000026D865B4A20> <__main__.Bar object at 0x0000026D865B4A20> <__main__.Bar object at 0x0000026D865B4A20>