Python——封裝


封裝指的是將對象的狀態信息隱藏在對象內部,不允許外部直接訪問對象內部信息,而是通過該類提供的方法來實現對內部信息的操作和訪問;封裝的含義,實際上,是把該隱藏的隱藏起來,該暴露的暴露出來;Python只需要將類的成員名為以雙下划線開頭,就可以隱藏類中的成員。

一、封裝數據屬性

例:

class Fraction:
	__grade = 0
	def __init__(self,name):
		self.__name = name
		
	def setting_grade(self,var):
		if isinstance(var,int) and var >= 0 and var <=100:
			Fraction.__grade = var
		else:
			print ('請輸入正確的分數!')
			
	def setting_name(self,set_name):
		if isinstance(set_name,str):
			self.__name = set_name
		else:
			print ('請輸入正確的姓名!')
			
	def get_fraction(self):
		print ('%s分數是:%s'%(self.__name,Fraction.__grade))

F = Fraction('小黃')    
print (F.__grade)    # 報錯 AttributeError: 'Fraction' object has no attribute '__grade'
print (F.__name)    # 報錯 AttributeError: 'Fraction' object has no attribute '__name'

F.get_fraction()    # 打印 小黃分數是:0

F.setting_name('小明')
F.setting_grade(100)    # setting_grade()、setting_name()會對用戶設置grade、name進行控制,符合條件才能允許設置

F.get_fraction()    # 打印 小明分數是:100

# 可以使用 _類名來訪問或修改對象的實例變量
print (F._Fraction__grade)    # 打印 100
print (F._Fraction__name)    # 打印 小明

上面例子中,代碼print (F.__grade)和print (F.__name)直接訪問私有變量會報錯setting_grade()、setting_name()方法用於對grade、name進行設置,只有符合條件才能允許設置;print (F._Fraction__grade)和print (F._Fraction__name)通過 _類名來訪問對象的實例變量(通常不要這么做),可以看出Python並沒有實現真正隱藏,只是改變以雙下划線開頭的變量,在這些變量前添加單下畫線和變量名。

 

二、封裝函數屬性

例:

class SumFraction:
	def __init__(self,usually,test):
		self.__usually = usually
		self.__test = test
		
	def set_usually_score(self,usually_var):
		if isinstance(usually_var,int) and usually_var >= 0 and usually_var <=100:
			self.__usually = usually_var
		else:
			print ('請輸入正確的分數!')
			
	def set_test_score(self,test_var):
		if isinstance(test_var,int) and test_var >= 0 and test_var <=100:
			self.__test = test_var
		else:
			print ('請輸入正確的分數!')
			
	def __calculation(self):    # 私有方法,只能內部使用,對外部隱藏運算邏輯
		return self.__usually * 0.3 + self.__test * 0.7
	
	def final_grade(self):
		return self.__calculation()

S = SumFraction(100,50)
print (S.final_grade())    # 打印 65.0
print (S.__calculation())    # 調用隱藏的__calculation()方法,會報錯 AttributeError: 'SumFraction' object has no attribute '__calculation'
print (S._SumFraction__calculation())    # 可以使用_類名方法名調用(不推薦這樣做),打印 65.0

# 修改__usually和__test
S.set_usually_score(70)
S.set_test_score(100)
print (S.final_grade())    # 通過final_grade()方法內部進行訪問__calculation()私有方法,打印 91.0

上面代碼中,set_usually_score()和set_test_score()用於對usually 、test進行設置;__calculation()是私有方法,默認是隱藏的,只允許內部使用,外部使用會報錯,當然也可以使用_類名方法名調用,但並不推薦這么做;print (S.final_grade())通過final_grade()方法內部訪問__calculation()私有方法。

 

三、property

先看一下幫助文檔:

>>> help(property)
Help on class property in module builtins:

class property(object)
 |  property(fget=None, fset=None, fdel=None, doc=None)
 |  
 |  Property attribute.
 |  
 |    fget
 |      function to be used for getting an attribute value
 |    fset
 |      function to be used for setting an attribute value
 |    fdel
 |      function to be used for del'ing an attribute
 |    doc
 |      docstring
 |  
 |  Typical use is to define a managed attribute x:
 |  
 |  class C(object):
 |      def getx(self): return self._x
 |      def setx(self, value): self._x = value
 |      def delx(self): del self._x
 |      x = property(getx, setx, delx, "I'm the 'x' property.")
 |  
 |  Decorators make defining new properties or modifying existing ones easy:
 |  
 |  class C(object):
 |      @property
 |      def x(self):
 |          "I am the 'x' property."
 |          return self._x
 |      @x.setter
 |      def x(self, value):
 |          self._x = value
 |      @x.deleter
 |      def x(self):
 |          del self._x
 |  
 |  Methods defined here:
 |  
 |  __delete__(self, instance, /)
 |      Delete an attribute of instance.
 |  
 |  __get__(self, instance, owner, /)
 |      Return an attribute of instance, which is of type owner.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __set__(self, instance, value, /)
 |      Set an attribute of instance to value.
 |  
 |  deleter(...)
 |      Descriptor to change the deleter on a property.
 |  
 |  getter(...)
 |      Descriptor to change the getter on a property.
 |  
 |  setter(...)
 |      Descriptor to change the setter on a property.
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __isabstractmethod__
 |  
 |  fdel
 |  
 |  fget
 |  
 |  fset

  

@property 可以在一個類中把方法變成同名屬性調用,能用屬性的方式來訪問該屬性。

@x.setter 表示可寫,最大作用是用於限制屬性的定義,x是被@property修飾的方法名,@x.setter修飾的方法名@property修飾的方法名必須同名。

@x.deleter 表示可刪除,x是被@property修飾的方法名,@x.deleter修飾的方法名@property修飾的方法名必須同名。

例:

class SumFraction:
    
    def __init__(self,value):
        self.__score = value

    @property    # 讀
    def score(self):
        print ('讀......')
        return self.__score
	    
    @score.setter       # 寫
    def score(self,var):
        print ('寫......')
        if isinstance(var,int) and var >= 0 and var <=100:
            self.__score = var
            return self.__score
        else:
            print ('請輸入正確的分數!')
            return

    @score.deleter    # 刪除
    def score(self):
        print ("刪除self.__score......")
        del self.__score

				

S = SumFraction(100)
S.score = 80    # 寫,打印 改......

print (S.score)    
'''
讀,打印 
讀......
80
'''

del S.score    # 刪除,打印 刪除self.__score......
print (S.score)    # __score已被刪除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score'

  

用property類來實現,例:

class SumFraction:
    
    def __init__(self,value):
        self.__score = value

    def get_score(self):
        print ('讀......')
        return self.__score
	    	
    def set_score(self,var):
        print ('寫......')
        if isinstance(var,int) and var >= 0 and var <=100:
            self.__score = var
            return self.__score
        else:
            print ('請輸入正確的分數!')
            return

    def del_score(self):
        print ("刪除self.__score......")
        del self.__score

    score = property(get_score,set_score,del_score,'這里是屬性含義~ ')
				

S = SumFraction(100)
S.score = 80    # 寫,打印 改......

print (S.score)    
'''
讀,打印 
讀......
80
'''

print (SumFraction.score.__doc__)  # 屬性含義,打印 這里是屬性含義~

del S.score    # 刪除,打印 刪除self.__score......
print (S.score)    # __score已被刪除,打印 AttributeError: 'SumFraction' object has no attribute '_SumFraction__score'

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM