4月16日 python學習總結 封裝之property、多態 、classmethod和staticmethod
阿新 • • 發佈:2018-04-16
.get 控制 radi code 學習 eth setter mysql area
一、封裝之property
@property把一個函數偽裝成一個數據類型
@偽裝成數據的函數名.setter 控制該數據的修改,修改該數據時觸發
@偽裝成數據的函數名.delect 控制該數據的刪除,刪除該數據時觸發
class People: def __init__(self,name): self.__name=name @property #將name()函數偽裝成一個數據屬性name def name(self): #obj.name print(‘您現在訪問的是用戶名。。。‘) return self.__name @name.setter #obj.name=‘EGON‘ 執行 name=x 修改 name 值時觸發該方法 def name(self,x): # print(‘=================‘,x) if type(x) is not str: raise TypeError(‘名字必須是str類型,傻叉‘) self.__name=x @name.deleter # 執行 del 對象.name 時觸發該方法def name(self): # print(‘就不讓你刪‘) del self.__name obj=People(‘egon‘) # print(obj.name) # print(obj.name()) # print(obj.name) # obj.name=‘EGON‘ # print(obj.name) # obj.name=123 del obj.name obj.name
二、多態
1、 什麽是多態
多態指的是同一種事物多種形態
2、為什要用多態
用基類創建一套統一的規則,強制子類去遵循(使用抽象類實現),這樣便可以
在不用考慮對象具體類型的前提下而直接使用對象下的方法
3、多態性:一種調用方式,不同的執行效果(多態性)
註意:多態與多態性是兩種概念
4、多態的使用
-
- 繼承
class Animal: def eat(self): pass def bark(self): print(‘叫‘) class Cat(Animal): def jiao(self): print(‘喵喵喵‘) class Dog(Animal): def speak(self): print(‘汪汪汪‘) class Pig(Animal): def han(self): print(‘哼哼哼‘) c=Cat() d=Dog() p=Pig() # 多態性:可以在不用考慮對象具體類型的前提下而直接使用對象下的方法 # c.eat() # d.eat() # p.eat() # d.bark() # p.bark() # c.bark() d.speak() c.jiao() p.han()
- 抽象類
import abc #abstract class class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def eat(self): pass @abc.abstractmethod def bark(self): pass # obj=Animal() # 抽象基類本身不能被實例化 class Cat(Animal): def eat(self): print(‘cat eat‘) def bark(self): print(‘喵喵喵‘) class Dog(Animal): def eat(self): print(‘dog eat‘) def bark(self): print(‘汪汪汪‘) class Pig(Animal): def eat(self): print(‘pig eat‘) def bark(self): print(‘哼哼哼‘) c=Cat() d=Dog() p=Pig() # c.bark() # d.bark() # p.bark() # def BARK(Animal): 向上轉型 # Animal.bark() # # # BARK(c) # BARK(d) # BARK(p)
- 鴨子類型(長得像鴨子就被當作是鴨子)
class Foo: def f1(self): print(‘from foo.f1‘) def f2(self): print(‘from foo.f2‘) class Bar: def f1(self): print(‘from bar.f1‘) def f2(self): print(‘from bar.f2‘) obj1=Foo() obj2=Bar() obj1.f1() obj1.f2() obj2.f1() obj2.f2() class Disk: def read(self): print(‘disk read‘) def write(self): print(‘disk write‘) class Txt: def read(self): print(‘txt read‘) def write(self): print(‘txt write‘) class Process: def read(self): print(‘process read‘) def write(self): print(‘process write‘) obj1=Disk() obj2=Txt() obj3=Process() obj1.read() obj2.read() obj3.read()
- 繼承
三、classmethod和staticmethod
classmethod
綁定方法:
在類內部定義的函數,默認就是給對象來用,而且是綁定給對象用的,稱為對象的綁定方法
1. 綁定對象的方法特殊之處:
應該由對象來調用,對象來調用,會自動將對象當作第一個參數傳入
2. 綁定到類的方法特殊之處:
應該由類來調用,類來調用,會自動將類當作第一個參數傳入
import settings class People: def __init__(self,name,age): self.name=name self.age=age def tell(self): print(‘%s:%s‘ %(self.name,self.age)) @classmethod def from_conf(cls): return cls(settings.NAME,settings.AGE) # p=People(‘egon‘,19) # p.tell() # p1=People(settings.NAME,settings.AGE) # p1.tell() # p2=People(settings.Name,settings.AGE) # p3=People(‘alex‘,74) # p3.tell() # print(People.from_conf) # p4=People.from_conf(People) # print(People.from_conf) # p4=People.from_conf() # p4.tell()
2、staticmethod:
非綁定方法,就是一個普通函數
特性: 既不跟類綁定,也不跟對象綁定,這意味著誰都能用
誰來用都是一個普通函數,也就是說沒有自動傳值的特性了
import settings import hashlib import time class People: def __init__(self,name,age): self.uid=self.create_id() self.name=name self.age=age def tell(self): print(‘%s: %s:%s‘ %(self.uid,self.name,self.age)) @classmethod def from_conf(cls): return cls(settings.NAME,settings.AGE) @staticmethod def create_id(): m=hashlib.md5() m.update(str(time.clock()).encode(‘utf-8‘)) return m.hexdigest() obj=People(‘egon‘,18) # print(obj.uid,obj.name,obj.age) # obj.tell() # print(obj.create_id) # print(People.create_id) print(obj.create_id()) print(People.create_id())
作業、
‘‘‘ 4月16 ‘‘‘ ‘‘‘ 1、定義MySQL類(參考答案:http://www.cnblogs.com/linhaifeng/articles/7341177.html#_label5) 1.對象有id、host、port三個屬性 2.定義工具create_id,在實例化時為每個對象隨機生成id,保證id唯一 3.提供兩種實例化方式,方式一:用戶傳入host和port 方式二:從配置文件中讀取host和port進行實例化 4.為對象定制方法,save和get_obj_by_id,save能自動將對象序列化到文件中,文件路徑為配置文件中DB_PATH,文件名為id號, 保存之前驗證對象是否已經存在,若存在則拋出異常,;get_obj_by_id方法用來從文件中反序列化出對象 ‘‘‘ import hashlib import time import pickle import os from days22 import setting class MySQL: def __init__(self, host, port): self.__host = host self.__port = port self.__id = self.create_id() @staticmethod def create_id(): m = hashlib.md5() m.update(str(time.clock()).encode(‘utf-8‘)) return m.hexdigest() @classmethod def creae_mysql(cla): return cla(setting.HOST, setting.PORT) def save(self): path = os.path.join(setting.DB_PATH, ‘%s.pk‘ % self.__id) if os.path.exists(path): raise ImportError(‘該id已存在‘) else: with open(path, ‘wb‘)as f: pickle.dump(self, f) def get_obj_by_id(self): path = os.path.join(setting.DB_PATH, ‘%s.pk‘ % self.__id) if not os.path.exists(path): raise ImportError(‘該id不存在‘) # print(‘該id不存在‘) else: with open(path, ‘rb‘)as f: return pickle.load(f) # m1 = MySQL(‘h1‘, ‘p1‘) # m2 = MySQL.creae_mysql() # # m2.save() # print(m2.get_obj_by_id().__dict__) # # # m1.save() # m1.get_obj_by_id() ‘‘‘ 2、定義一個類:圓形,該類有半徑,周長,面積等屬性,將半徑隱藏起來,將周長與面積開放 參考答案(http://www.cnblogs.com/linhaifeng/articles/7340801.html#_label4) ‘‘‘ class Circle: def __init__(self,radius): self.__radius=radius @property def perimeter(self): return 2*(3.14)*self.__radius @property def area(self): return (3.14)*(self.__radius**2) # c1=Circle(3) # print(c1.area) # print(c1.perimeter) ‘‘‘ 3、明日默寫 1、簡述面向對象三大特性:繼承、封裝、多態 繼承:繼承是一種新建類的方式,新建類稱之為子類或派生類,父類稱之為基類或者超類,子類會‘遺傳’父類的屬性 封裝:裝就是把一對屬性裝起來,封就是把這些屬性藏起來 封裝對外隱藏,對內開放 多態:一種事物的多種形態;多態主要體現在繼承、抽象類抽象方法、鴨子類型 多態性:調用同方一方法,有不同的執行效果 2、定義一個人的類,人有名字,身高,體重,用property講體質參數封裝成人的數據屬性 class People: def __init__(self,name,hight,weight): self.__name=name self.__hight=hight self.__weight=weight @property def bmi(self): return self.__weight/(self.__hight**2) 3、簡述什麽是綁定方法與非綁定方法,他們各自的特點是什麽? 綁定方法:在類內部定義的函數,默認就是給對象來用,而且是綁定給對象用的,稱為對象的綁定方法 若該函數是綁定給類用的,稱之為類的綁定方法 非綁定方法:既不跟類綁定,也不跟對象綁定,這意味著誰都能用 誰來用都是一個普通函數,也就是說沒有自動傳值的特性了 ‘‘‘
4月16日 python學習總結 封裝之property、多態 、classmethod和staticmethod