Python廖雪峯教程學習筆記:Day9

前言

養成一個好的習慣只需要堅持21天,Day9

訪問限制

由上一節定義的Student類來看,我們可以在外部代碼修改name、score屬性。比如我們想要修改對象的成績,可以直接對score賦值。

bart.score = 60
print(bart.score)
# 60

如果要讓內部的屬性不被外部訪問和修改,我們可以在屬性的名稱前面加上兩個下劃線__,這樣就變成了一個私有對象,只有內部可以訪問,外部不可以訪問。即在外部即不能訪問也不能進行修改。

class Student(object):
	
	def __init__(self,name,score):
		self.__name = name
		self.__score = score
	def print_score(self):
		print('%s: %s' % (self.__name, self.__score))
bart  = Student('Bart Simpon',99)

在外部訪問實例變量的屬性:

bart.__name
# ---------------------------------------------------------------------------
# AttributeError                            Traceback (most recent call last)
# <ipython-input-2-b54cbc8ec6d2> in <module>()
# ----> 1 bart.__name

#AttributeError: 'Student' object has no attribute '__name'

這樣確保了外部代碼不能隨便的改變對象內部的狀態,如果在限制訪問的同時想要允許外部代碼進行訪問或者修改的話,就可以給類增加getset方法。

class Student(object):
	...
	# get方法,獲取對象的name、score屬性
	def get_name(self):
		return self.__name
	def get_score(self):
		return self.score
	
	# set方法,改變對象的name、score屬性
	def set_name(self,name):
		self.__name = name
	def set_score(self,score):
		if 0 <=score<= 100:
			self.__score = score
		else:
			 raise ValueError('bad score')

在Python中,類似__xxx__的變量是特殊變量,特殊變量在外部是可以訪問的,不是私有變量。有時候我們會看到一個下劃線開頭的變量名,比如_name,這樣命名的意思是“雖然我可以被訪問,但是請把我視爲私有變量,不要隨意訪問。”
雙線劃線開頭的變量也不是一定不能訪問,而是不能直接訪問,如果使用baer._Student__name來訪問也可以等到name變量。

bart._Student__name
# 'Bart Simpson'

練習
請把下面的Student對象的gender字段對外隱藏起來,用get_gender()和set_gender()代替,並檢查參數有效性:

class Student(object):
    def __init__(self, name, gender):
        self.name = name
        self.__gender = gender
    def get_gender(self):
        return self.__gender
    def set_gender(self,gender):
        if gender in ('male','female'):
            self.__gender = gender
        else:
            raise ValueError('bad gender')
# 測試:
bart = Student('Bart', 'male')
if bart.get_gender() != 'male':
    print('測試失敗!')
else:
    bart.set_gender('female')
    if bart.get_gender() != 'female':
        print('測試失敗!')
    else:
        print('測試成功!')
# 測試成功!

繼承和多態

在OOP程序設計中,當我們定義一個class類時,我們可以從已有的class繼承,新的class類成爲子類(Subclass),原有的class稱爲父類(Base class)。
首先,我們編寫一個animal類,使用run()方法直接打印:

class Animal(object):
	def run(self):
		print('Animal is running...')

繼續編寫DogCat類時,就可以直接從Animal類繼承,把Animal寫在類名後面的括號裏,就代表Dog繼承Animal類,Cat同理:

class Dog(Animal)pass
class Cat(Animal):
	pass

繼承之後,子類獲得了父類的全部功能。在此處,DogCat類就繼承了Animal類的run()方法。

dog = Dog()
dog.run()
cat = Cat()
cat.run()
# Animal is running...
# Animal is running...

接着對子類增加一些方法:

class Dog(Animal):
	def run(self):
		print('Dog is running...')
		
class Cat(Animal):
    def run(self):
        print('Cat is running...')

對子類增加方法後執行:

dog = Dog()
dog.run()
cat = Cat()
cat.run()
# Dog is running...
# Cat is running...

雖然子類繼承的父類中也有run()方法,但是子類的run()覆蓋了父類的run(),這就是繼承的多態表現。要判斷一個變量是否是某個類型可以使用isinstance()判斷:

b = Dog()
isinstance(b,Dog)
# true
發佈了9 篇原創文章 · 獲贊 20 · 訪問量 1631
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章