面向對象
和java一樣,OOP把對象作為程序的基本單元,一個對象包含了數據和操作數據的函數。
不同之處是python中方法也是對象,這和js有點類似
類
類是創建實例的模板,而實例則是一個一個具體的對象,各個實例擁有的數據都互相獨立,互不影響;
class Student(object):
- 通過關鍵字class來聲明
- class之后是類名
- ()內object是繼承的類,如果沒有合適的繼承類,就使用object類,這是所有類最終都會繼承的類;和java中的Object類似
- 創建對象方式:
s = Student()
- 和js類似,可以自由給一個對象綁定屬性
#綁定name屬性
s.name="sfdsfd"
#打印出屬性值
print(s.name)
- 定義構造方法__init___,和java中的構造器類似,第一個參數必須是self,調用時,不需要傳入,python解釋器會自動傳入對象本身,需要注意的是,如果定義了__init___,創建實例時,傳參必須和__init___方法的參數一致
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
- 該類中的方法,要訪問類的數據,聲明時第一個參數要是self,調用時,不需要聲明,這個方法是與實例綁定的函數,和普通函數不同,方法可以直接訪問實例的數據
#定義Student類
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))
#調用
s=Student('Tom', 90);
s.print_score()
聲明私有變量
以__開頭,且不能以__結尾來定義這個成員變量為私有變量,外部通過 變量名.屬性名 的方式不能直接訪問
class Student(object):
def __init__(self, name, score):
self.__name=name
self.__score=score
s = Student('Tom', 90)
print(s.__name)
運行后會報錯
Traceback (most recent call last):
File "/Users/demo/workspace/pythonDemo/src/Demo.py", line 8, in <module>
print(s.__name)
AttributeError: 'Student' object has no attribute '__name'
注意:這種定義私有變量的方式只是和解釋器的一種約定,實際上,不能直接訪問__name是因為Python解釋器對外把__name變量改成了_Student__name,所以,仍然可以通過_Student__name來訪問__name變量,我們要遵守這種約定,不要試圖使用_Student__name的方式來訪問這種變量,不同版本的Python解釋器可能會把__name改成不同的變量名,
多態和繼承
和java的思想一樣,主要目的是實現代碼的重用,遵循對擴展開放,對修改封閉
值得注意的地方是,python是動態語言,方法調用時,不需要明確傳參的具體類型,主要能夠保證方法內的邏輯,也就是這個參數有某個方法即可,java是強制性語言,必須嚴格類型。
常用對象的方法
#返回123的類型
type(123)
#判斷fn是否是函數
type(fn)==types.FunctionType
#
type(abs)==types.BuiltinFunctionType
#判斷是否是lambda表達式
type(lambda x: x)==types.LambdaType
#
type((x for x in range(10)))==types.GeneratorType
#判斷s是否是Student類型
isinstance(s, Student)
#輸出一個字符串的所有屬性,返回值為一個包含字符串的list
dir('ABC')
# 判斷s是否有屬性'_Student__name'嗎?
hasattr(s, '_Student__name')
# 設置屬性
setattr(s, 'age', 19)
# 獲取屬性,如果沒有返回默認值-1
getattr(s, 'age', -1)
類的屬性和對象的屬性區分
類屬性是公開的,對象的屬性如果和類屬性重名,會覆蓋類屬性
浙公網安備 33010602011771號