python圣斗士修炼(十二):给你介绍个对象!

关于类的定义和对象的实例化

作为一门面向对象的语言,类和对象可谓是重中之重,掌握了这一块,才能真正说是学会了python。
先来介绍下关于类和对象的名词吧:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法

定义一个简单的类,用于录入员工信息:

class Employee(object):
   '所有员工的基类'
   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
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

先分析上述的代码我们做了什么:

  • class Employee:
    我们定义了一个类,类名字叫Employee,默认的继承对象是object,object是一切对象的父类也叫基类。
  • ‘所有员工的基类’ :
    紧跟在类定义后面的这个字符串叫做类的文档字符串,用来写说明文档。
  • empCount = 0:
    定义类的属性 empCount,用于统计员工编号,可以在外部直接调用。
  • def __init__(self, name, salary):
    形如def xxx的格式就是在类的内部实现的函数,叫做类的方法,和普通函数不同的是所有类的方法的第一个参数都是self,但在调用的时候不需要传入这个参数,因为参数这个参数表示的是类的实例本身,调用的时候会自动传入。 __init__方法是类的内置方法之一。在实例化的时候执行的第一个方法就是init,它规定了实例化的格式,比如此处我们就要求传入name和salary,2个参数。
  • def displayCount(self):
    类的普通方法,这里的功能是输出对象的员工号。
  • def displayEmployee(self):
    类的普通方法,这里的功能是打印对象的员工号和工资。
  • emp1 = Employee(“Zara”, 2000)
    实例化了第一个员工,通过执行Employee.__init__(“Zara”, 2000) 创建了一个对象emp1,但实例化的过程不仅仅做了这些,类的方法会自动绑定到每个对象上,也就是说此时我们可以直接执行emp1.displayCount()和 emp1.displayEmployee()。

    -emp1.displayEmployee():
    调用displayEmployee方法,此时应该会输出

 Name :  Zara ,Salary:  2000
  • print “Total Employee %d” % Employee.empCount

    打印类的属性.empCount:此时结果为:

    Total Employee 2

类的定义完整版

class People(object):
    color='yellow'  #类的公有属性  可以在外部直接访问
    __age=30  #类的私有属性       可以通过方法调用 self.__age 访问
    def  __init__self,name):   #类的内置方法,初始化的时候需要传入定义的参数
        self.Name=name
        return self.name
        self.sex()
        self.__age()
    def  sex(self,SEX):             #类的公有方法,可以在类的外部和对象外部调用
        if SEX=='M' || SEX=='W'self.sex=SEX
        self.var1='对象的公有属性'
        self.__var2='对象的私有属性'
    def __age(self,age_num):    #类的私有方法,只能在类的内部调用
        self.__age=age_num

    @classmethod    #类方法修饰器,使得方法可以通过类外部访问
    def classaddess(self)
        print '类方法'
    @staticmethod  #静态方法修饰器,使得方法可以通过类外部访问
    def staticcard()
        print People.color
   @property    #特性修饰器。将方法变成字段的访问形式
    def Bar(self):
  print self.Name

修改类的函数

● getattr(obj, name[, default]) : 访问对象的属性。定义当用户访问一个不存在的属性时候的行为。
● getattribute(self,name):定义该类属性被访问时的行为。
● hasattr(obj,name) : 检查是否存在一个属性。返回bool
● setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。定义用户设置一个属性时的行为。
● delattr(obj, name) : 删除属性。定义当用户删除一个属性时候的行为。

hasattr(emp1, ‘age’) # 如果存在 ‘age’ 属性返回 True。
getattr(emp1, ‘age’) # 返回 ‘age’ 属性的值
setattr(emp1, ‘age’, 8) # 添加属性 ‘age’ 值为 8
delattr(empl, ‘age’) # 删除属性 ‘age’

查看类的属性

查看类的属性:
dir(C)

>
[‘class‘, ‘delattr‘, ‘dict‘, ‘doc‘, ‘format‘, ‘getattribute‘, ‘hash‘, ‘init‘, ‘module‘, ‘new‘, ‘reduce‘, ‘reduce_ex‘, ‘repr‘, ‘setattr‘, ‘sizeof‘, ‘str‘, ‘subclasshook‘, ‘weakref‘]

C.class:实例C对应的类(仅新式类)
C.doc:类C对应的文档字符串
C.dict:类C的属性
C.module:类C所在的模块
C.call:将类C变成一个可调用对象。
范例:
class Person:
…: def init(self,name):
…: self.name=name
…: def call(self,friend):
…: print(‘%s 的好基友是%s’ % (self.name,friend))
…:
P=Person(‘小康康’)
P(‘大康康’)

小康康 的好基友是大康康

关于类的继承

继承,顾名思义就知道是它的意思,举个例子说明:你现在有一个现有的A类,现在需要写一个B类,但是B类是A类的特殊版,我们就可以使用继承,B类继承A类时,B类会自动获得A类的所有属性和方法,A类称为父类,B类陈为子类,子类除了继承父类的所有属性和方法,还可以自定义自己的属性和方法,大大增加了代码的复用性。
我们可以继承了object类,object类是所有类的父类,所有的类都默认继承object类,它是一个超级类,如果不写,默认继承object。
继承类的格式:
class A(父类):

Python的类支持多继承,下面我们来看一下多继承的格式:
class A: # 定义类 A
…..

class B: # 定义类 B
…..

class C(A, B): # 继承类 A 和 B
…..
多继承其实在需要在父类的位置,直接写多个父类就可以,然后用“,”分开就可以了,C类就同时继承了A类和B类。
Python类的继承注意事项:
1.在继承中类的构造(__init()方法)不会自动调用,它需要在子类的构造中亲自调用。
2. Python总是首先子类中的方法,如果子类没有找到,才回去父类中查找

实例:

import random as r
class Fish():
def  __init__(self):
self.x=r.randint(0.10)
self.y=y.randint(0.10)
def move(self):
self.x-=1
print('我的位置是:'self.x,self.y)
class Goldfish(Fish):
pass
class Carp(Fish):
pass
class Salmon(Fish):
pass
class Shark(Fish):
def __init__(self):    #此时会自动覆盖父类对象的init方法,因此没有初始坐标。
self.hungry=True
def eat(self):
if self.hungry:
print('我要吃饭')
self.hungry=False
else:
print('我现在不饿')

Shark无法调用move方法,因为init方法被重写了,解决方法:
第一种:调用未绑定的父类方法
def init(self):
Fish.init(self)
self.hungry=True
第二种:使用super方法:自动获取基类方法
def init(self):
super().init()
self.hungry=True
判断对象类型:一个类其实就是一种数据类型
子类方法执行的时候先看子类定义是否重写了该方法,如果没有就去父类找该方法。
super语句:
单继承时super()和init()实现的功能是类似的

class Base(object):  
        def __init__(self):  
            print 'Base create'  
    class childA(Base):  
        def __init__(self):  
            print 'creat A ',  
            Base.__init__(self)  
    class childB(Base):  
        def __init__(self):  
            print 'creat B ',  
            super(childB, self).__init__()  
    base = Base()  
    a = childA()  
    b = childB()  

关于super函数:
代码一:

class A:
def __init__(self):
print("Enter A")
print("Leave A")

class B(A):
def __init__(self):
print("Enter B")
A.__init__(self)
print("Leave B")

class C(A):
def __init__(self):
print("Enter C")
A.__init__(self)
print("Leave C")

class D(A):
def __init__(self):
print("Enter D")
A.__init__(self)
print("Leave D")

class E(B, C, D):
def __init__(self):
print("Enter E")
B.__init__(self)
C.__init__(self)
D.__init__(self)
print("Leave E")

E()

结果:

Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E

执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。

代码二:

class A:
def __init__(self):
print("Enter A")
print("Leave A")

class B(A):
def __init__(self):
print("Enter B")
super(B, self).__init__()
print("Leave B")

class C(A):
def __init__(self):
print("Enter C")
super(C, self).__init__()
print("Leave C")

class D(A):
def __init__(self):
print("Enter D")
super(D, self).__init__()
print("Leave D")

class E(B, C, D):
def __init__(self):
print("Enter E")
super(E, self).__init__()
print("Leave E")

E()

结果:

Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E

在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照mro进行的(E.mro)。
:E.mro
(main.E, main.B, main.C, main.D, main.A, object)
关于MRO算法:
http://www.360doc.com/content/16/0719/18/34574201_576833790.shtml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值