[学习笔记]python之面向对象编程

python之面向对象编程

__init__

  • 通过在类中定义一个特殊的__init__方法,在创建实例的时候想要进行属性初始化,想要一些必要的属性的值绑上去时:

        class Person(object):
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
  • __init__方法的第一个参数要为self,self表示创建的实例本身.书写__init__方法,在创建实例的时候,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。

  • __init__ 方法的返回值总是None,不要试图给其返回其他的东西。

  • __init__ 方法并不是在创建实例时第一个被调用的方法,第一个被调用的是__new__(cls[,...]) 方法,如果__new__方法后面有参数,该方法会将参数传给__init__方法 , 最终通常返回一个实例对象。一般不需要我们重写__new__方法。

__new__

  • 例子

        class Upstr(str):
        def __new__(cls, string):
            string = string.upper()
            return str.__new__(cls,string)
    
  • 上面通过定义自身__new__方法来实现字符串的大写转换:首先调用参数的大写化方法,后直接调用字符串本身的__new__方法。

  • 当子类中不写__new__方法时,子类自动调用父类的__new__方法。

  • 注意__new__ 方法需要返回一个实例对象,当不返回东西时,将不会再去调用__init__ 方法。

__del__

  • 当对象将要被销毁时,这个方法将自动调用。

  • del x 不等同与 x.__del__() 当所有对某个实例的引用全都被del x时,才会去调用__del__ 方法。

访问限制

  • 如果想让内部属性封装起来,可以在属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

    class Person(object):
    
    def __init__(self, name):
        self.__name = name
    
    def get_name(self):
        return self.__name
    

继承

  • 当我们定义一个class的时候,可以从某个现有的class继承:可在新类右边的括号上添加继承的类名:

    class New_str(str):
    
        def new(self):
        print('I am new str...')
    
  • 在python中,当一个类什么类也不继承时,自动继承object类。python中一个类还可以继承多个类,实现不同层面的继承。继承可实现方法的覆盖

    class Animal:
        def __init__(self,name):
            self.name = name
        def hello(self):
            print 'animal'
    
    class Runnable:
        def __init__(self,speed):
            self.speed = speed
        def hello(self):
            print 'runnable'
    
    class Dog(Animal,Runnable):
    
        #重写构造方法后,将父类的构造方法覆盖掉了,解决方法:使用类方法
        def __init__(self,name,speed,age):
            Animal.__init__(self,name)
            Runnable.__init__(self,speed)
            self.age = age
        def hello(self):
            print 'dog'
    
    
    c = Dog('Helen',113,13)
    c.hello()
    print c.__dict__  #返回一个字典
    

多态

a = Animal()
d = Dog()
>>> isinstance(c, Dog)
True
>>> isinstance(c, Animal)
True 
  • 由上我们可知,d不仅是Dog类的实例,还是Animal类的实例。所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来不行。

  • 多态的好处在于:定义函数的参数类型的时候可以用父类的数据类型,这样继承父类的各个子类都是作为实参传入进去。

__str__

  • 定义一个类时,我们可以给它添加__str__ 的魔法方法,这样打印(print)这个类的实例时,不会打印其地址,而是打印出我们想要的信息。如:

    class A:
        def __init__(self,name):
            self.name = name
        def __str__(self):
            return self.name
    
    a = A('Mary')
    print(a)
    

对象的属性

  • 判断对象是否有某种属性

    class MyObject(object):
        def __init__(self):
            self.x = 9
    
    obj = MyObject()
    print hasattr(obj,'x')
    print getattr(obj,'x') 
    # x属性不存在时,会出现异常。
    # 这时可以传入一个default参数,如果属性不存在,就返回默认值
    print getattr(obj,'y',19) 
    
    setattr(obj, 'x', 19)
    print obj.x
    
  • 对象的方法名和属性名不要相同。

  • 给实例对象绑定属性

    class Student(object):
        def __init__(self, name):
            self.name = name
    
    s = Student('Bob')
    s.score = 90  # 但类的属性中不存在score
    print s.score 
    
  • 给属性绑定方法

    class A:   # 定义一个类
        pass
    
    a = A()
    
    def set_age(self, age):       # 定义一个方法
        self.age = age
    
    from types import MethodType
    a.set_age = MethodType(set_age, a)  
    # 给实例a绑定方法,类还是不存在该方法
    a.set_age(25)
    print a.age
    
  • 限制实例的属性,不允许其添加新的属性:

    class Student(object):
        __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
    
    s = Student()
    s.age = 12
    s.name = 'xxx'
    s.score = 150 # 左边这样做会出现异常
    

类的属性

  • 定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到:

    class Student:
        school = 'xxxx'
    
    a = Student()
    print a.school # 访问的是类的school属性
    b = Student()
    a.school = 'cccc'  
    # 给对象a绑定了新属性school,这里的school并不是类的属性
    del a.school # 删除对象a的新属性
    print b.school
    print a.school
    
  • 不要把实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

  • 给类绑定新的方法

    class B:
        pass
    
    b = B()
    
    def set_age(self, age):
        self.age = age
    from types import MethodType
    B.set_age = MethodType(set_age, B) # 给类绑定新的方法
    b.set_age(12)
    print b.age
    

检查参数,使用@property

class Student:

    @property               # 定义属性
    def score(self):
        return self._score  # 区分属性_score和方法score

    @score.setter           # 定义属性的set方法
    def score(self,value):  
        if not (isinstance(int, value)):
            raise ValueError('score must be an integer!')
        elif value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值