面向对象-python

基本形式:
以student为例:

class Student(object):
    pass

class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
创建实例:

>>> bart = Student()
>>> bart
<__main__.Student object at 0x10a67a590>
>>> Student
<class '__main__.Student'>

给实例绑定属性:

>>> bart.name = 'Bart Simpson'
>>> bart.name
'Bart Simpson'

类可以起到模板的作用,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去,通过定义一个特殊的__init__方法。
绑定基本属性:

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

注:__init__方法的第一个参数永远是self,表示创建的实例本身,可以把各种属性绑定到self。
创建实例:

>>> bart = Student('Bart Simpson', 59)
>>> bart.name
'Bart Simpson'
>>> bart.score
59

注意:不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去

数据封装

用类中的方法去访问数据,无需调用外面的函数访问数据。
类的方法:

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)

调用方法:

>>> bart.print_score()
Bart Simpson: 59

封装的好处:

  • 只调用不关注内部实现细节。
  • 可以给类增加新的方法。

如增加get_grade:

class Student(object):
    ...

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'
>>> bart.get_grade()
'C'

私有变量:

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)

确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
外部要获取私有变量的方法:

class Student(object):
    ...

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

外部要修改私有变量的方法:

class Student(object):
    ...

    def set_score(self, score):
        self.__score = score

可以对参数做检查,避免传入无效的参数:

class Student(object):
    ...

    def set_score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

特殊变量如:namescore 可以直接访问。
单下划线变量如:_name 代表“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

继承

animal继承object:

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

编写Dog和Cat类时,就可以直接从Animal类继承:

class Dog(Animal):
    pass

class Cat(Animal):
    pass

子类调用父类方法:

dog = Dog()
dog.run()

cat = Cat()
cat.run()

对子类增加方法:

class Dog(Animal):
    def run(self):
        print 'Dog is running...'
    def eat(self):
        print 'Eating meat...'

当子类和父类都存在相同的run()方法时,子类的run()覆盖了父类的run()

多态

我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样:

a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型

判断一个变量是否是某个类型可以用isinstance():

>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> isinstance(c, Dog)
True

函数接受animal类型变量:

def run_twice(animal):
    animal.run()
    animal.run()

传入animal类型实例:

>>> run_twice(Animal())
Animal is running...
Animal is running...

传入dog类型实例:

>>> run_twice(Dog())
Dog is running...
Dog is running...

传入cat类型实例:

>>> run_twice(Cat())
Cat is running...
Cat is running...

在定义一个tortoise类型,也从animal派生:

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

传入tortoise类型实例:

>>> run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...

新增一个Animal的子类,不必对run_twice()做任何修改就可以使用。
著名的“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

总结图:

获取对象信息

判断对象类型:

>>> type(123)
<type 'int'>
>>> type('str')
<type 'str'>
>>> type(None)
<type 'NoneType'>

如果一个变量指向函数或者类,也可以用type()判断:

>>> type(abs)
<type 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>

python定义了每种type类型的常量,放在types模块中:

>>> import types
>>> type('abc')==types.StringType
True
>>> type(u'abc')==types.UnicodeType
True
>>> type([])==types.ListType
True
>>> type(str)==types.TypeType
True

所有类型都是TypeType类型。

>>> type(int)==type(str)==types.TypeType
True

能用type()判断的基本类型也可以用isinstance()判断:

>>> isinstance('a', str)
True
>>> isinstance(u'a', unicode)
True
>>> isinstance('a', unicode)
False

判断一个变量是否是某些类型中的一种:

>>> isinstance('a', (str, unicode))
True
>>> isinstance(u'a', (str, unicode))
True

获取一个对象的所有属性:

>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

类似__xxx__的属性和方法在Python中都是有特殊用途的

>>> len('ABC')
3
>>> 'ABC'.__len__()
3

写一个__len__()方法:

>>> class MyObject(object):
...     def __len__(self):
...         return 100
...
>>> obj = MyObject()
>>> len(obj)
100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值