一 類命名空間與對象、實例的命名空間
創建一個類就會創建一個類的名稱空間,用來存儲類中定義的所有名字,這些名字稱為類的屬性
而類有兩種屬性:靜態屬性和動態屬性
- 靜態屬性就是直接在類中定義的變量
- 動態屬性就是定義在類中的方法
?
class Person:Country = '中國人' # 靜態變量print(Person.Country) alex = Person() # 創建了一個空的命名空間 alex.name = 'alex' # 對象 alex.Country = '泰國人' egon = Person() egon.name = 'egon' # 類名.靜態變量 對象.屬性名 # 類名可以調用對象的屬性么? 不可以 # 對象可以調用類中的屬性么? 可以 print(Person.Country)#中國人 print(alex.Country)#泰國人 print(egon.Country)#中國人# 由于對象和類之間存在一個關聯關系 # 所以對象能夠找到類 # 但是 類不能找到對象 # # 使用類名.屬性 只會尋找類中的靜態變量名字 # 使用對象.屬性 會現在對象自己的命名空間中找名字 # 如果找不到 再到類的內存空間中去找
?
?
?
其中類的數據屬性是共享給所有對象的
>>>id(egg.role) 4341594072 >>>id(Person.role) 4341594072
?
而類的動態屬性是綁定到所有對象的
>>>egg.attack <bound method Person.attack of <__main__.Person object at 0x101285860>> >>>Person.attack <function Person.attack at 0x10127abf8>?
?
創建一個對象/實例就會創建一個對象/實例的名稱空間,存放對象/實例的名字,稱為對象/實例的屬性
在obj.name會先從obj自己的名稱空間里找name,找不到則去類中找,類也找不到就找父類...最后都找不到就拋出異常?
?
?
class Person:money = 0mother = Person() father = Person() Person.money += 1000#類的靜態屬性等于1000 Person.money += 1000#類的靜態屬性等于2000 print(Person.money)#類的money屬性等于2000 print(mother.money)#媽媽調用類的money等于2000 print(father.money)#父親調用類的money屬性也等于2000
?
?
?
class Person:money = [0]#類的money的命名空間有一個列表,列表里是0 mother = Person()#媽媽開通一個空的命名空間 father = Person()#父親開通一個命名空間 mother.money[0] += 1000#媽媽的命名空間里創建一個列表,列表里第一位索引等于1000元 father.money[0] += 1000#父親的命名空間里創建一個列表,列表里第一位索引等于2000元 print(Person.money)#2000 print(mother.money)#2000 print(father.money)#2000
?
?
?
class Person:money = [0]mother = Person() father = Person() mother.money = [1000]#媽媽的money屬性賦予新變量[1000] father.money = [2000]#爸爸的money屬性賦予新的變量[2000] print(Person.money)#對象的money屬性無法改變,類的money屬性[0] print(mother.money)#直接打印媽媽的新的變量屬性[1000] print(father.money)#直接打印爸爸的新的變量屬性[2000]
?
?
?
面向對象的組合用法
軟件重用的重要方式除了繼承之外還有另外一種方式,即:組合
組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組合
# 組合 兩個類的事兒 # 什么叫組合 : 一個類對象的屬性 是 另外一個類的對象 # 兩個類的事兒 :類與類之間有一種"什么有什么的關系"
?
?
圓的類
圓環 和 圓
圓環 也是一個類
屬性 大圓半徑 和 小圓半徑
圓環 求面積 求周長
# 圓環 from math import pi class Circle:#創建一個圓的類def __init__(self,r):#初始化圓的對象,定義一個半徑rself.r = rdef area(self):#圓的面積return pi*(self.r**2)def perimeter(self):#圓的周長return 2*pi*self.r c1 = Circle(5)#c1是半徑為5的圓#實例化 #c1.perimeter()#對象的調用周長屬性 class Ring:#創建一個同心圓def __init__(self,outer,inner):#初始化同心圓的外環,內環self.outer = Circle(outer) # 組合Ring的屬性是,Circle類的實例化對象self.inner = Circle(inner)# 組合Ring的屬性是,Circle類的實例化對象def area(self):#圓環的面積等于外環的面積?內環的面積return self.outer.area() - self.inner.area()def perimeter(self):#圓環的周長等于外環的周長+內環的周長return self.outer.perimeter() + self.inner.perimeter()
?
老師 name sex course(課程) birth
生日 年月日
?
class Birthday:#生日類def __init__(self,year,month,day):#初始化對象self.year = year#生日類(被傳入的對象)的年屬性self.month = month#生日類的月屬性self.day = day#生日類的日屬性 class Teacher:#教師類def __init__(self,name,sex,course,birth):#初始化對象self.name = name#教師類(對象)的name屬性self.sex = sex#教師的sex屬性self.course = course#教師的course的屬性self.birth = birth # birth是一個對象 birth = Birthday(1960,3,7) # birth 是Birthday類的一個對象 alex = Teacher('alex','male','python',birth)#Alex對象傳入一個birth屬性 # alex.birth = birth # # time # '1960-3-7' # # 老師的年齡 2018 - 1960# print(birth) # import time # if birth.month == time.localtime().tm_mon and \ # birth.day == time.localtime().tm_mday: #如果調用birth類的月屬性等于結構化時間的月,日屬性等于結構化時間的日 # print('生日快樂')#打印生日快樂 # print(time.localtime().tm_year - birth.year)#用結構化年份-生日年份等于年齡
?
?
?
?