python講稿4_1 類1 屬性綁定和引用

1 python類

1.1 python類定義

class Employee:
   '所有員工的基類'
   empCount = 0
 
   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print("Total Employee %d" % Employee.empCount)
 
   def displayEmployee(self):
      print("Name : ", self.name,  ", Salary: ", self.salary)
  • python中有時將變量和函數(方法)統稱爲屬性.
    • empCount是類屬性,類的所有對象公用.
    • name,salary是實例(對象)屬性,不同的對象各自持有
    • displayEmployee是實例(對象)屬性(方法)
    • 此例中沒有類方法屬性
  • self 代表類的實例
  • 所有的成員函數的第一參數都是self,說明成員函數都需要通過實例化的具體對象來調用
  • init()方法是類的構造函數
>>>p1=Employee('xufei1',2000)
>>>p1.displayEmployee()
Name:xufei1, Salary:2000
>>>Employee.empCount # 也可以p1.empCount
1
>>>p2=Employee('zs1',3000)
>>>p2.displayEmployee()
>>>Employee.empCount 
2

注意: python不支持構造函數__init__的重載,
但可以使用缺省參數的方式.

class Employee:
   empCount = 0
 
   def __init__(self, name='無', salary=None):
      self.name = name
      self.salary = salary
      Employee.empCount += 1

調用如下:

>>>p1=Employee()
>>>p2=Employee('xufei1')
>>>p3=Employee('xufei1',2000)
>>>p1.displayEmployee()
>>>p2.displayEmployee()
>>>p3.displayEmployee()
>>>Employee.empCount
Name :  空 , Salary:  None
Name :  xufei1 , Salary:  None
Name :  xufei1 , Salary:  2000
3

1.2 屬性綁定

**注意:**在類和具體對象中都有一個內置屬性__dict__

1.2.1 類屬性綁定

  • 類定義時,比如Employee中的empCount
  • 運行時任意階段
>>>Employee.__dict__
mappingproxy({'__dict__': <attribute '__dict__' of 'Employee' objects>,
              '__doc__': None,
              '__init__': <function __main__.Employee.__init__(self, name='空', salary=None)>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Employee' objects>,
              'displayCount': <function __main__.Employee.displayCount(self)>,
              'displayEmployee': <function __main__.Employee.displayEmployee(self)>,
              'empCount': 0})
>>>p1.__dict__
{'name': '空', 'salary': None}

其中empCount是類定義時綁定的類屬性,下面演示動態綁定類屬性

>>>Employee.guimo='big'
>>>Employee.__dict__
mappingproxy({'__dict__': <attribute '__dict__' of 'Employee' objects>,
              '__doc__': None,
              '__init__': <function __main__.Employee.__init__(self, name='空', salary=None)>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Employee' objects>,
              'displayCount': <function __main__.Employee.displayCount(self)>,
              'displayEmployee': <function __main__.Employee.displayEmployee(self)>,
              'empCount': 0,
              'guimo': 'big'})
>>>p1.__dict__
{'name': '空', 'salary': None}

運行演示:

>>>Employee.guimo
big
>>>p1.guimo
big

1.2.2 實例屬性的綁定

與類屬性綁定相同,實例屬性綁定也發生在兩個地方:

  • 類定義時,如name,age
  • 運行時任意階段
>>>p1.addr='beijing'
>>>p1.__dict__
{'addr': 'beijing', 'name': '空', 'salary': None}
>>>p2.__dict__
{'name': 'xufei1', 'salary': None}

注意: 可見,不同對象可以綁定不同的屬性,相互之間不通用.

1.3 屬性引用

1.3.1 類屬型引用

類數據屬性
>>>Employee.empCount
3
>>>Employee.guimo
big

此例中沒有類方法,我們將實例(對象)方法(屬性)displayCount更改爲類方法屬性如下:

class Employee:
   '所有員工的基類'
   empCount = 0
 
   def __init__(self, name='空', salary=None):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   @classmethod
   def displayCount(cls):
     print("Total Employee %d" % Employee.empCount)
 
   def displayEmployee(self):
      print("Name : ", self.name,  ", Salary: ", self.salary)

注意: 這裏使用了裝飾器@classmethod(後面講),同時displayCount的參數改爲cls

>>>Employee.empCount()
Total Employee 3

1.3.2 實例屬性引用

使用實例對象引用屬性稍微複雜一些,因爲實例對象可引用類屬性以及實例屬性。但是實例對象引用屬性時遵循以下規則:

  • 總是先到實例對象中查找屬性,再到類屬性中查找屬性;
  • 屬性綁定語句總是爲實例對象創建新屬性,屬性存在時,更新屬性指向的對象。

示例1:

class Dog:

    kind = 'canine'
    country = 'China'

    def __init__(self, name, age, country):
        self.name = name
        self.age = age
        self.country = country

dog = Dog('Lily', 3, 'Britain')
print(dog.name, dog.age, dog.kind, dog.country)

# output: Lily 3 canine Britain

類對象Dog與實例對象dog均有屬性country,按照規則,dog.country會引用到實例對象的屬性;但實例對象dog沒有屬性kind,按照規則會引用類對象的屬性。
示例2:

class Dog:

    kind = 'canine'
    country = 'China'

    def __init__(self, name, age, country):
        self.name = name
        self.age = age
        self.country = country
dog = Dog('Lily', 3, 'Britain')
dog.kind = 'feline'
dog.__dict__
結果爲:
{'age': 3, 'country': 'Britain', 'kind': 'feline', 'name': 'Lily'}
print(dog.kind)
print(Dog.kind)
結果爲:
feline
canine

注意: 1 改變dog.king並不會改變類屬性Dog.kind的值.
2 python類中形參第一個爲self的叫方法,形參不含有self的叫函數.

最後看一個例子:(get,set函數)

示例3 下面爲name屬性添加get和set函數.

class Employee:
    empCount = 0

    def __init__(self, name='空', salary=None):
        self.name = name
        self.salary = salary
        Employee.empCount += 1
    def get_name(self,name):
        return self.name
    def set_name(self,name):
        self.name=name

運行演示:

p1=Employee('xufei1',2000)
print(p1.get_name())
p1.set_name('zs1')
print(p1.get_name())

作業:
1 定義一個Student類,構造函數至少包含參數name,score, 定義類方法get_grade,根據學生的score分級,大於90分的爲’A’,60-90分之間的爲’B’,小於60分的爲’C’.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章