python 面向对象编程知识点

教程来源:廖雪峰大神的网站https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318645694388f1f10473d7f416e9291616be8367ab5000

面向对象编程

1、和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。Python解释器自己会把实例变量传进去。

2、和静态语言不同,Python允许对实例变量绑定任何数据。

3、访问限制。私有变量(变量名称以__开头)不可以被外部访问

4、变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的。因此,变量名称一定不要设成__xxx__

5、继承可以把父类的所有功能都直接拿过来。

6、多态的意义:当我们需要传入DogCatTortoise……时,我们只需要接收Animal类型就可以了,因为DogCatTortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法。(API的接口类型不固定)

7、动态语言的鸭子特性:animal只是个形参,只要传入的参数是一个有run()方法的对象就可以。对于静态语言(例如Java)来说,传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

class Animal(object):

      pass

def run_twice(Animal):

      Animal.run()

8、对象或者变量的类型

isinstance(a,b)判断的是一个对象a是否是某种类型。继承的子类的对象属于父类

type():可以是int,str,types.FunctionType,types.BuiltinFunctionType等等

9、实例属性和类属性

类属性的绑定在类内完成:

class student(object):

       self.name=....

实例属性的绑定:

s=student()

s.name=...

当实例属性和类属性的名称相同且同时存在时,实例属性的优先级会高于类属性。

面向对象高级编程

  • 枚举类

from enum import Enum, unique

@unique
class Gender(Enum):
    Male = 0
    Female = 1

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

bart = Student('Bart', Gender.Male)#gender就由字符串类型变成了int类型
  • 利用__function__定制类

python的class中有很多有特殊用途的函数,它们的格式都是这样的:__function__(注意前后都是双下划线)

1.__str__()

class student(object):

...

print(student('jane'))

此时在打印时,调用了__str__函数

2.__repr__()

s=student('jane')

s

__repr__是在直接敲变量而不是print时调用的

一个简单做法:__repr__=__str__

3.__iter__()和__next__()用于for...in...迭代语句

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 # 返回下一个值

Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误(异常情况)时退出循环。

4.__getitem__()

__iter__和__next__无法返回一个list类型的结果。

5.__getattr__()

当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性

作用:动态化处理类的属性和方法的调用。e.g.链式调用调用API

6.__call__()

s = Student('Michael')

当定义__call__()后,s除了是一个实例外,还可以当作一个函数

可以通过callable()函数判断某一个对象是不是可调用的

7.__len__()

__slots__

创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。

但是,在实际中,我们往往不希望某个类的实例可以被绑定任意的属性和方法。因此可以给__slots__变量用赋值一个tuple,来定义能被添加的属性名称。要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

  • @property(装饰器)

如果直接用类的属性初始化,就无法检查属性的参数是否正确。因此,还是需要set和get方法来对实例进行操作。这样操作起来会比较复杂。@property是python内置的一个装饰器函数,它可以把class的方法变成属性。

把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值。如果该属性是一个只读属性,那就不需要@score.setter了。

@property

def width(self):

       return self._width

@width.setter

def width(self,value):

      self._width=value

一定要注意的一点是:属性和方法一定不可以重名,解决方法,在属性前面加_,否则方法会一直调用它本身。

  • 多重继承

在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为MixIn。注意:JAVA就是只允许单一继承。

def dog(animal,runnable_mixin):

       pass

使用元类

用type()函数动态地创建类

 Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class

如果要控制类的创建行为,还可以使用metaclass。(这个目前超出了我的理解范围,以后再来填坑)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值