Python 5、面向对象

☆面向对象


定义类&创建实例:

class Person:
    pass
xiaoming = Person()

创建实例属性:
如上,先创建实例,再创建实例。动态语言嘛,与js相似
xiaoming.school = ‘CUIT’
xiaoming.age = 20
xiaoming.age = xiaoming.age + 1


初始化实例属性:
在定义Person类时,可以为Person类添加一个特殊的__init__()方法

class Person(object):
    def __init__(self, name, gender, birth):
        self.name = name
        self.gender = gender
        self.birth = birth

在创建实例的时候,就必须提供self以外的参数
xiaoming = Person(‘XiaoM’, ‘Male’, ‘1991-1-1’)

任务:
Person类除了接收name, gender, birth之外,还可以接收任意关键字参数

class Person(object):
    def __init__(self, name, gender, birth, **kw):
        self.name = name
        self.gender = gender
        self.birth = birth
        for k,v in kw.iteritems():
            setattr(self, k, v)
xiaoming = Person('小明', '男', '1990-1-1', job='student')
print xiaoming.job
==>student

访问限制:
Python对属性权限的控制是通过属性名来控制的
属性名 双下划线 (_ _),该属性就无法被外部访问

class Person(object):
    def __init__(self, name):
        self.name = name
        self._title = 'Mr'
        self.__job = 'student'
p = Person('Bob')
print p.name
==>Bob
print p._title
==>Mr
print -.__job
==>AttributeError

可见,只有以__开头的__job不能被外部访问
但是,若以_xxx_形式来定义,就被称为特殊属性,能被外界访问
有很多预定义的特殊属性可以使用,所以,通常不要把普通属性用_xxx_定义
以单下划线_xx开头的属性能被外界访问,但是按照习惯,它不应该被访问???


Python创建类属性:
实例属性,各自一份。类属性,共同一份

class Person(object):
    address = 'CUIT'
    def __init__(self, name):
        self.name = name
print Person.address
==>CUIT
p = Person('Bob')
p.address #这样也是可以的,以实例属性访问的方式访问类属性
==>'CUIT'
p.address = 'PKU'
Person.address
==>CUIT
p.address
==>PKU

类实例可以被修改,但是只能以Person.address的形式去访问他,并修改
实例p.address,可以理解为在实例p上新添加属性address


类属性名与实例属性名冲突:

Person.address = 'CUIT'
p.address = 'PKU'
print p.address
==>PKU
del p.address
print p.address
==>CUIT

可见,当实力属性与类属性重名时,实例属性优先于类属性,将屏蔽掉对类属性的访问
当我们将p的address属性删除后,访问p.address就是实例属性了


定义实例方法:
实例方法就是在类中定义的函数。第一个参数一定是self,指向实例本身,同Java中的this

class Person(object):
    def __init__(self, name):
        self.name = name
    def get_name(self):
        return self.name
#调用
p = Person('Bob')
print p.get_name() #self不需要显示地传入
==>Bob

在实例方法内部,可以访问所有实例属性。
这样,如果外部要访问 私有属性 可以通过方法调用
好处:数据封装,保护数据一致性,简化外部调用


方法也是属性:
我们在class中定义的实例方法也是属性,它实际上是一个函数对象

print p.get_name
==><Object......> #返回一个函数对象

但这个函数是一个绑定到实例的函数

因为方法也是属性,所以呢,它可以被动态地添加到实例上,只是需要types.MethodType() 把一个函数转变为方法

import types
def fn_get_grade(self):
    if self.score >= 80:
        return 'A'
    elif self.score >= 60:
        return 'B'
    return 'C'
class Person(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

p1 = Person('Bob', 90)
p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
print p1.get_grade()
==>A
p2 = Person('Alice', 65)
print p2.get_grade()
==>AttributeError
#因为p2没有绑定get_grade
#给一个实例动态添加方法并不常见,直接在class中定义更为直观
#函数与方法的表面区别就是:有没有参数`self`

Python中定义类的方法:
和属性类似,方法也分为实例方法和类方法
在class中定义的方法都是实例方法,实例方法的第一个参数self是实例本身。
在class中定义类方法,需要这么写:

class Person(object):
    count = 0
    @classmethod
    def how_many(cls):
        return cls.count

通常通过@classmethod来标识该方法绑定到Person类上,而非类的实例
类方法的第一个参数将传入类本身
通常将参数命名为cls上面的cls.count相当于Person.count
因为类方法在实例上调用,因此,无法获取任何实例属性,只能获取类的引用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值