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’.

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