python的類和實例化對象


一切皆對象,類也是對象,類來自於元類type,如果一個類沒有聲明自己的元類,默認它就是元類。

即類是元類的實例,通過type(類)會顯示type,而實例來自於類。

 

類有兩個屬性,數據屬性和函數屬性,下面是一個創建類和實例化對象的例子

class animal:
    'This is class for animal'  #類的說明
    type='animal'
    def __init__(self,name,sex,leg):
        self.name = name
        self.sex = sex
        self.leg = leg
    def eat(self,food):
        print('%s likes to eat %s'%(self.name,food))
    def play(self):
        print('%s is playing'%self.name)

print(animal.__name__)#打印類的名稱
print(animal.__doc__) #打印類的說明,__doc__屬性不能繼承給子類
print(animal.__dict__) #打印類的屬性字典

cat=animal('cat','male',4)
print(cat.__dict__) #打印類的屬性字典
print(cat.type)
cat.eat('mouse')
cat.play()

#執行結果
# animal
# This is class for animal
# {'__module__': '__main__', '__doc__': 'This is class for animal', 'haveTeeth': True, '__init__': <function animal.__init__ at 0x00000000021AA598>, 'eat': <function animal.eat at 0x00000000021AA620>, '__dict__': <attribute '__dict__' of 'animal' objects>, '__weakref__': <attribute '__weakref__' of 'animal' objects>}
# {'name': 'cat', 'sex': 'male', 'leg': 4}
# cat likes to eat mouse
# animal

在class animal:范圍下面的都是對animal類的定義,其中def __init__()是定義animal類的數據屬性,__init__()不應該有返回值,否則會報錯,其他函數則是animal類的函數屬性,可以看到類下面的函數的第一個參數都是self。

當執行cat=animal('cat','male',4),觸發animal類的__init__()函數生成一個cat實例。

__dict__表示屬性字典,以字典形式存放,通過打印animal.__dict__和cat.__dict__可以發現,類有數據屬性和函數屬性,而實例只有數據屬性沒有函數屬性,但是實例可以繼承和調用對象的函數屬性。

實例調用類的函數時,會自動將實例本身作為第一個參數傳給函數,但是類自己調用函數時不會自動將實例本身作為參數傳入,例如要通過類調用play()函數,則animal.play(cat)。

類的屬性字典是共用的,而實例的屬性字典是私有的。

 

類屬性的查看、增加、修改和刪除

#查看類的數據屬性
print(animal.type)
#修改類的數據屬性
animal.type='Animal'
print(animal.type)
#增加類的數據屬性
animal.haveteeth=True
print(cat.haveteeth)
#刪除類的數據屬性
del animal.haveteeth
#增加類的函數屬性,修改類似
def play_bal(self,ball):
    print('The %s is playing %s'%(self.name,ball))
animal.play_ball=play_bal
cat.play_ball('tennis')

 

實例屬性的增加

#增加實例的數據屬性,cat.__dict__['key']='value'也可以增加數據屬性但不建議使用
cat.living='land'
print(cat.__dict__)  #{'name': 'cat', 'sex': 'male', 'leg': 4, 'living': 'land'}
#刪除實例的數據屬性
del cat.living
print(cat.__dict__)  #{'name': 'cat', 'sex': 'male', 'leg': 4}
#修改實例的數據屬性
cat.sex='female'
print(cat.sex)  #female
#增加實例的函數屬性
def test():
    print('hello')
cat.test=test
cat.test()  #hello

 對於實例增加的函數屬性,實例在調用時不會自動將自身作為參數傳入。

 

需要注意的是:

如果在類前面定義了與類的數據屬性同名的全局變量,那么只要不通過類或者實例+.調用這個變量,這個變量就是指類前面定義的全局變量

如果實例增加了與類的數據屬性同名的屬性,相當於給實例增加了這個屬性,對類的屬性沒有影響。

type='mouse'
class animal:
    type='animal'
    l=['a','b']
    def __init__(self,name):
        self.name = name
        print(type)  #此處的type是指全局變量,而不是類內部的數據屬性變量

cat=animal('cat')
cat.type='male' #相當於給cat增加了一個數據屬性type,對類的type屬性沒有影響
print(cat.__dict__)
print(cat.type)
cat.l.append('c')#此處修改的是類的數據屬性l,與通過=賦值(給實例增加屬性)不同

 

__class__:實例來自哪個類

__module__:實例來自哪個模塊

 

類的組合

即在類實例化時,將另一個類的實例作為參數傳入,這樣可以將兩個實例關聯起來。

當類之間有顯著不同,並且較小的類是較大的類所需要的組件時,用組合比較好。

例如,描述一個機器人類,這個大類是由很多互不相關的小類組成,如機械胳膊類、腿類、電池類等。

當類之間有很多相同的屬性,提取這些統統的屬性做成基類,用繼承比較好。

class course:
    def __init__(self,name,price,period,teacher):
        self.name=name
        self.price=price
        self.period=period
        self.teacher=teacher
class teacher:
    def __init__(self,name,sex):
        self.name=name
        self.sex=sex
class student:
    def __init__(self,name,age,course):
        self.name=name
        self.age=age
        self.course=course
t1=teacher('Bob',38)
t2=teacher('Jack',45)
t3=teacher('Jane',45)
c1=course('python',6000,'3 months',t2)#將teacher作為參數傳遞給課程實例
c2=course('linux',7000,'5 months',t1)
c3=course('mysql',6500,'5 months',t3)
d={'1':c1,'2':c2,'3':c3}
name='Alice'
age=21
while True:
    choice=input('please choice course:')
    if choice in d.keys():
        s1=student(name,age,d[choice])#將課程實例作為參數傳遞給學生實例
        print(s1.__dict__)
        print('%s choose course %s,%s is the teacher'%(s1.name,s1.course.name,s1.course.teacher.name))
    elif int(choice)==0:
        exit(0)
    else:
        print('please input correct choice')
示例:類的組合

運行結果如下圖

 


免責聲明!

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



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