python面向对象初探

以下是我在python学习过程中,涉及到的关于python面向对象的一些记录,比较零散,如有错误的地方,恳请指教。

python类

在python中声明一个类:

class Student(Person):
    #声明'构造函数'(其实是一个用来传参的初始化函数)
    def __init__(self, name, score):
        self.name = name
        self.score = score
    #声明自定义函数
    def print_score(self):
        print self.score    
生成该类的一个对象
stu = Student(name='abc', score=12)

python中的属性分为类属性(和python中的静态变量一样,所有对象公用一份),常量(定义在一个.py文件中一般的常量)和对象属性(数据属性),在python中数据属性定义在__init__方法中

对象添加属性,或者给属性赋值(类似js,Python允许动态添加实例变量并绑定任何数据,python是一门动态语言)

stu.age = 18

如果要让内部属性不能被外部访问,可以在属性的前面加上,在python中,实例的变量名如果以开头,就变成一个私有变量(private),只有内部可以访问,外部是不能访问的

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

可以给私有变量添加get和set方法
    def get_name(self):
        return self.__name
    def set_name(self, name):
        self.__name = name

给实例添加方法
def set_age(self, age):
    self.age = age

from types import MethodType
s.set_age = MethodType(set_age, s, Student) #给实例绑定一个方法
Student.set_age = MethondType(set_age, None, Studet) #给class绑定方法
python中的绑定

python中严格要求,没有实例,方法是不能被调用的。非绑定的方法 可能可以被调用,但实例对象一定要明确给出,才能确保调用成功。然而,不管是否绑定,方法都是它所在的类的固有属性(而不是实例属性),即使它们几乎总是通过实例来调用的。python类中定义的方法,第一个参数self就是要绑定的实例。

继承

继承描述了基类的属性如何“遗传”给派生类。一个子类可以继承它的基类的任何属性,不管 是数据属性还是方法。(私有属性也会被继承,但是无法被访问到)

常用的特殊的类属性

属性名含义
__name__类名(字符串)
__doc__文档字符串
__bases__所有父类构成的元组(仅能通过类名调用)
__dict__对象的所有属性(不包含其父类)
__module__类定义所在的module
__class__实例对应的类

通过继承重写父类的方法,python中没有重载,所以子类的方法名如果和父类一致就会重写父类的方法

__init__()如果没有在子类中显式定义该方法,在实例创建完成之后会直接调用父类的__init__(),如果在子类中定义了该方法,则父类中的__init__()默认不会执行,除非显示调用父类的__init__()

super(className, self).parentFunc() 其父类必须要显示的继承object,才能调用super()。如果不显式继承object 生成的类的type就是 < type ‘classobj’ >, 而不是< type ‘type’ > 这是一个历史遗留问题, 所以我们在声明一个类的时候要显式继承object

def childFunc(self):
    super(childFunc, self).parentFunc()

多继承,子类在调用方法的时候会现在自己的类中找,如果找不到就去父类中找,规则是先广度,后深度。在设计类的继承关系时,通常,主线都是单一继承下来的,需要为某个类加入某个功能的时候,才会去用到多继承(Mixin的设计)。

class P1(object):
    def foo(self):
        print 'from P1'

    def bar(self):
        print 'bar from P1'

class P2(object):
    def foo(self):
        print 'from P2'

class C1(P1, P2):
    pass

class C2(P1, P2):#这个位置改成P2,P1的时候,GC就不能同时继承c1,c2了。
    def bar(self):
        print 'bar from C2'
    pass

class GC(C1, C2):
    pass

if __name__ == '__main__':
    c = C1()
    c.foo()
    c = C2()
    c.foo()
    gc = GC()
    gc.bar()
定制类

列举出一些常用的定制类的方法

__str__() 和java中的toString类似,重新定义toString方法

def __str__(self):
    return 'aaa'

__repr__ ()和上面的方法作用是类似的 用于python交互界面直接输入对象时的输出

__iter__() 如果一个类想被用于for … in 循环 就必须要实现这个方法 该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __iter__(self):
        return self # 实例本身就是迭代对象,故返回自己

    def next(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration();
        return self.a # 返回下一个值

__getitem__() 可以实现按照下标取值

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

__getattr__() 当我们访问一个对象不存在的属性时,会调用这个方法,比如,这个对象中没有定义score 当我们访问score属性的时候,就会调用这个方法

__getattr__(self, 'score')
def __getattr__(self, attr):
        if attr=='score':
            return 99

__call__() 定义__call__()函数, 对象就变成一个可调用的对象

class Student(object):
    def __init__(self, name):
        self.name = name
    def __call__(self):
        print('My name is %s.' % self.name)
s = Student('xiaoming')
s()

__call__()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。
如果你把对象看成函数,那么函数本身其实也可以在运行期动态创建出来,因为类的实例都是运行期创建出来的,这么一来,我们就模糊了对象和函数的界限。

那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call()__的类实例:
动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,二十运行时动态创建的。

python对象

python使用对象模型来存储数据,构造任何类型的值都是一个对象

所有python对象都有三个特性:身份, 类型, 值
身份

每个对象都有一个唯一的身份标识自己,任何对象的身份都可以使用内建函数id()来得到,这个值可以被认为是该对象的内存地址

类型

对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。内建函数Type()可以用来查看Python对象的类型,另外,python中类型也是对象(Python是一门面向对象的语言。) Type()的返回值是对象,而不是一个简单的字符串。

对象表示的数据项
上面三个特性在对象创建的时候就被赋值,除了值之外,其它两个特性都是只读的。
如果对象支持更新操作,那么它的值就可以改变,否则他的值也是只读的。对象的值是否可以更改被称为对象的可改变性。只要一个对象没有被销毁,这些特性就一直存在。

在python中,类型就是数据类型;类就是类型,实例是对应类型的对象。

标准类型

数字,整型,布尔值,长整型,浮点型,复数型,字符串,列表,元组,字典。
标准数据类型也叫基本数据类型。

其他内建类型

类型,Null对象(None), 文件,集合/固定集合,函数,模块,类。

所有的类也是对象,他的类型是type;type也是所有Python类型的根和所有Python标准类的默认元类(metaclass)。

python中的特殊类型Nonetype,它只有一个值,那就是None.它不支持任何运算,也没有任何内建方法。

实例化过程:person = Pserson(), python会帮你生成一个对象返回给你,这个对象是该类的一个实例,然后检查__init__(self)方法是否存在,如果存在,调用该方法,其中self就是第一步生成的对象。如果不存在,调用父类中的__init__()方法

面向对象相关内建方法

函数名用法
isinstance(obj1, obj2)判断obj1是否是obj2的一个实例
hasattr(obj, s)判断obj中是否有s这个属性
getattr(obj, s)返回obj的属性s的值
setattr(obj, s, value)设置obj中的s属性值为value
deleteattr(obj, s)从obj中删除s这个属性
vars(obj)它包含了对象存储于其dict中的属性(键)及值,给定对象必须包含dict属性

dir()函数

  • dir()作用在实例上(经典类或新式类)时,显示实例变量,还有在实例所在的类及所有它 的基类中定义的方法和类属性。
    • dir()作用在类上(经典类或新式类)时,则显示类以及它的所有基类的dict中的内容。 但它不会显示定义在元类(metaclass)中的类属性。
    • dir()作用在模块上时,则显示模块的dict的内容。(这没改动)。
    • dir()不带参数时,则显示调用者的局部变量。(也没改动)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值