1. 程式人生 > >python:屬性查找與綁定方法

python:屬性查找與綁定方法

就會 value gre def 名稱空間 計數器 不能 list 如果

屬性查找

類有兩種屬性:數據屬性和函數屬性

1、類的數據屬性是所有對象共享的

# 類的數據屬性是所有對象共享的,id是一樣的
print(id(OldboyStudent.school))     # 4830576
print(id(s1.school))        # 4830576
print(id(s2.school))        # 4830576
print(id(s3.school))        # 4830576

  

2、 類的函數屬性是綁定給對象用的,稱為綁定到對象的方法

# 類的函數屬性是綁定給對象使用的,obj.method稱為綁定方法,內存地址都不一樣
print(OldboyStudent.learn)      # <function OldboyStudent.learn at 0x0000000002879598>
print(s1.learn)                 # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866898>>
print(s2.learn)                 # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x00000000028669E8>>
print(s3.learn)                 # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866F98>>

#ps:id是python的實現機制,並不能真實反映內存地址,如果有內存地址,還是以內存地址為準

  在obj.name會先從obj自己的名稱空間裏找name,找不到則去類中找,類也找不到就找父類,最後都找不到就拋出異常

綁定方法

定義類並實例化出三個對象

class OldboyStudent:
    school = ‘oldboy‘
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def learn(self):
        print(‘%s is learning‘ % self.name)     # 新增self.name

    def eat(self):
        print(‘%s is eating‘ % self.name)

    def sleep(self):
        print(‘%s is sleeping‘ % self.name)


s1 = OldboyStudent(‘李坦克‘, ‘男‘, 18)
s2 = OldboyStudent(‘王大炮‘, ‘男‘, 28)
s3 = OldboyStudent(‘牛彈琴‘, ‘女‘, 38)

  類中定義的函數(沒有被任何裝飾器裝飾的)是累的函數屬性,類可以使用,但必須遵循函數的參數規則,有幾個參數需要傳幾個函數

OldboyStudent.learn(s1)         # 李坦克 is learning
OldboyStudent.eat(s2)            # 王大炮 is eating
OldboyStudent.sleep(s3)        # 牛彈琴 is sleeping  

類中定義的函數(沒有被任何裝飾器裝飾的),其實主要是給對象使用的,而且是綁定到對的,雖然所有對象指向的都是相同的功能,但是綁定到不同的對象就是不同的綁定方法

強調:綁定到對象的方法的特殊之處在於,綁定給誰就由誰來調用,誰來調用,就會將誰本身當做第一個參數轉給方法,即自動傳值(方法__init__也是一樣的道理)

s1.learn()  # 等同於OldboyStudent.learn(s1)
s2.eat()    # 等同於OldboyStudent.eat(s2)
s3.sleep()  # 等同於OldboyStudent.sleep(s3)

  註意:綁定到對象的方法的這種自動傳值的特征,決定了在類中定義的函數都要默認寫一個參數self,self可以是任意名字,但是約定俗成地寫在self

類即類型

  Python中一切皆為對象,且Python3中類與類型是一個概念,類型就是類

#類型dict就是類dict
>>> list
<class ‘list‘>

#實例化的到3個對象l1,l2,l3
>>> l1=list()
>>> l2=list()
>>> l3=list()

#三個對象都有綁定方法append,是相同的功能,但內存地址不同
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8>

#操作綁定方法l1.append(3),就是在往l1添加3,絕對不會將3添加到l2或l3
>>> l1.append(3)
>>> l1
[3]
>>> l2
[]
>>> l3
[]
#調用類list.append(l3,111)等同於l3.append(111)
>>> list.append(l3,111) #l3.append(111)
>>> l3
[111]

  

小節練習

# 練習1:編寫一個學生類,產生一堆學生對象, (5分鐘)
#
# 要求:
#
# 有一個計數器(屬性),統計總共實例了多少個對象

class Student():
    school = "家裏蹲大學"
    count = 0

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
        Student.count += 1

    def learn(self):
        print(‘%s is learning‘ % self.name)

s1 = Student(‘張三‘, ‘男‘, 22)
s1.learn()
s2 = Student(‘李四‘, ‘女‘, 28)
print(Student.count)
print(s1.count)

# 練習2:模仿三國定義兩個英雄類, (10分鐘)
#
# 要求:
#
# 英雄需要有昵稱、攻擊力、生命值等屬性;
# 實例化出兩個英雄對象;
# 英雄之間可以互毆,被毆打的一方掉血,血量小於0則判定為死亡。
class Garen:
    camp = ‘Demacia‘

    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity
        if enemy.life_value <= 0:
            print(‘%s已經死亡‘ % self.nickname)

class Riven:
    camp = ‘Noxus‘

    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity
        if enemy.life_value <= 0:
            print(‘%s已經死亡‘ % self.nickname)


g1 = Garen(‘曹操‘, 100, 30)
r1 = Riven(‘劉備‘, 100, 50)

print(r1.life_value)
g1.attack(r1)
g1.attack(r1)
g1.attack(r1)
g1.attack(r1)
print(r1.life_value)

  

python:屬性查找與綁定方法