Python面向对象编程

类和实例

在Python中,定义类是通过class关键字,注意类名要大写首字母:

class Student(object):
    pass

定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:bart = Student()
可以自由地给一个实例变量绑定属性,比如,给实例bart绑定一个name属性:bart.name = 'Bart Simpson'
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去:

class Studetn(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

__init__方法的第一个参数永远是self,表示创建的实例本身,有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,bart = Student('Jack', 59)
我们可以在类的内部定义访问类的数据的函数,这些函数叫做方法:

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print('%s: %s' % (self.name, self.score))

通过这些方法就可以在外部直接访问类的数据,而不需要知道具体实现的细节。

访问限制

在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问:

class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score
    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

继承和多态

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类,而被继承的class称为基类、父类或超类。
比如,我们已经编写了一个名为Animal的class:

class Animal(object):
    def run(self):
        print('Animal is running...')

当我们需要编写Dog类时,就可以直接从Animal类继承:

class Dog(Animal):
	pass

继承最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法。
给Dog类也加一个run()方法,子类的run()覆盖了父类的run(),这就是继承的另一个好处,多态:一个类他可以拥有多种状态,实质上就是说它本身就有多个类型。

__slot__的作用

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。如果我们想要限制实例的属性,比如,只允许对Student实例添加name和age属性,为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

class Student(object):
	__slot__ = ('name', 'age')

然后:


>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

socre属性不在__slot__中,所以无法绑定
使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的,除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

使用@property

Python内置的@property装饰器就是负责把一个方法变成属性调用的:

class Student(object):
    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

这样就把一个set_score的方法变成了一个属性赋值,就拥有了一个可控的属性操作,可以对score的赋值进行限制,比起直接定义一个set_score要方便许多:

>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值