面向对象编程

面向过程:根据业务逻辑从上到下垒代码

函数式:将某功能代码封装到函数中,以后直接调用,不需要再次编写

面向对象:对函数进行分类和封装,让开发“更快更好更强...”

# 像Java和C#等编程语言仅支持面向对象编程,而Python支持函数式编程和面向对象编程混用

面向对象示例

# 函数式编程def bar():    print('bar') bar()  # 直接调用函数# 面向对象编程class Foo:  # 创建类      def bar(self):  # 在类里面定义函数 这里self是一个特殊的参数 创建对象时Foo将自身传进来        print('bar') obj = Foo()  # 创建一个对象obj.bar()  # 由对象去访问类里面函数

  

面向对象的三大特性:封装 继承 多态

封装

将我们需要的内容封装进创建的类,需要的时候再去调用

class Foo:  # 创建类     def __init__(self, name, age):  # Foo接收到两个参数后会封装在自己类内部        self.name = name        self.age = age  obj = Foo('kobe', 18)  # 创建一个对象 传两个参数print(obj.name, obj.age)  # 外面调用封装好的参数 输出:kobe 18

类成员

字段:普通字段、静态字段

方法:普通方法、静态方法、类方法

属性:普通属性

1)字段(类里面封装的参数)

class Foo:    # 字段(静态字段 保存在类里面)    CC = "中国"    def __init__(self, name):        # 字段(普通的字段 保存在对象里面)        self.name = name # 普通字段通过对象访问obj = Foo('上海')print(obj.name)# 静态字段通过类访问print(Foo.CC)

2)方法(类里面封装的函数)

class Foo:     def show(self):              # 普通方法:对象调用执行 方法属于类        print(self.name)     @staticmethod    def f1():        # 静态方法 由类调用执行        print('f1')     @classmethod    def f2(cls):  # class 自动给类名传进去了        # 类方法        # cls 是类名 加()创建对象        print(cls) # 创建对象obj = Foo()# 通过对象去访问普通方法 obj.show()# 通过类去访问静态方法Foo.f1()# 类方法 会将类 Foo 名字直接传入函数Foo.f2()

3)属性

在没有定义类的属性之前,我们访问类中的方法需要在方法名后面加括号():比如 obj.f1()

定义属性之后,我们访问类中的方法可以直接 obj.f1

class Foo:    @property    def f1(self):        print('f1') obj = Foo()obj.f1  # 无需加括号直接通过对象访问

可设置、可删除

class Foo:     @property  # 在类方法上加上 property装饰器     def f1(self):        print('f1')     @f1.setter  # 设置数值    def f1(self, values):        print(values)     @f1.deleter  # 可删除    def f1(self):        print('del...') obj = Foo()obj.f1  # 无需加括号直接通过对象访问 obj.f2 = 100del obj.f1 输出:f1del...

类属性的另一种写法

class Foo:     def f1(self):        return 100     def f2(self, value):        print(value)     def f3(self):        print('300')          # 类属性定义    Foo = property(fget=f1, fset=f2, fdel=f3) obj = Foo() # 取值ret = obj.Fooprint(ret) # 赋值obj.Foo = 200 # 删除del obj.Foo # 输出100200300

 

类成员修饰符

类成员修饰符:将类中的字段或者方法定义为公有或私有

公有成员:在任何地方都可以访问

私有成员:只有在类内部才能被访问

class Foo:     __cc = 123     def __init__(self, name):        self.__name = name  # 加两个下划线__表示私有字段 外部、继承都不能调用     def f1(self):        print(self.__name)     @staticmethod  # 加 staticmethod 装饰器表示为静态方法,可以不加self参数直接外部调用    def f3(self):        print(Foo.__cc) obj = Foo('kobe')# print(obj.__name)  # 通过对象外部访问内部普通字段不成功obj.f1() # print(Foo.__cc)  # 通过外部访问内部静态字段也不成功obj.f3() # 特殊访问方法print(obj._Foo__name)

 

类的特殊成员

__doc__       # 类的描述信息

__module__     # 当前对象在哪个模块

__class__      # 当前对象属于哪个类

__str__       # 打印对象时返回的值

__init__      # 构造方法

__del__       # 析构方法

__call__      # 对象后加括号触发执行

__dict__      # 类或对象中的所有成员

__getitem__    # 索引操作如字典

__setitem__    # 索引操作

__delitem__    # 索引操作

1)__doc__ 描述信息

class Foo:    """    注释 __doc__    """obj = Foo()print(obj.__doc__)输出:注释 __doc__2)__module__ 和 __class__from lib.aa import C obj = C()print obj.__module__  # 输出 lib.aa,即:输出模块print obj.__class__      # 输出 lib.aa.C,即:输出类

3)__init__ 和 __str__

class Foo:     def __init__(self, name, age):  # 构造方法        self.name = name        self.age = age    def __str__(self):  # str方法        return '%s - %s ' % (self.name, self.age) obj1 = Foo(name='kobe', age=18)obj2 = Foo(name='jordan', age=18)print(obj1)print(obj2)# 输出:kobe - 18 jordan - 18

4)__del__

class Foo:      def __init__(self, name, age):  # 构造方法        self.name = name        self.age = age      # 析构方法:在垃圾回收之前执行    def __del__(self):        pass

5)__call__

class Foo:     def __call__(self, *args, **kwargs):        print('call') p = Foo() # 对象后面加括号执行 __call__ 方法p()# 一个括号是类创建了一个对象 两个括号是去执行 __call__ 方法Foo()() # 输出:callcall

6)__dict__

class Foo:      def __init__(self, name, age):  # 构造方法        self.name = name        self.age = age  obj1 = Foo(name='kobe', age=18) # 获取对象中封装的数据返回一个字典ret = obj1.__dict__print(ret)# 输出:{'name': 'kobe', 'age': 18} # 全部的类方法# print(Foo.__dict__)

6)__getitem__ __setitem__ delitem__ 用于索引操作、如字典:可以获取值、设置、删除

class Foo:     def __getitem__(self, item):        print('getitem')     def __setitem__(self, key, value):        print('setitem')print(item.start, item.stop, item.step)     def __delitem__(self, key):        print('delitem') # 中括号语法自动执行 getitem 方法obj = Foo()obj['ab'] # 中括号并且赋值执行 setitem 方法obj['k1'] = 111del obj['k1'] # 切片也是去执行 setitem 方法obj[1:6:2] # 输出setitemdelitemgetitem1 6 2

7)__iter__、 __isinstance__、__issubclass__ 

class Bar:    pass class Foo(Bar):        # 返回一个可迭代对象    def __iter__(self):        # return iter([11, 22, 33, 44])        yield 1        yield 2 obj = Foo()for item in obj:    print(item) # 查看 obj 是否是 Foo 的实例ret = isinstance(obj, Foo)# 也可以查看是否是 父类 的实例# ret = isinstance(obj, Bar)print(ret) # 查看 Foo 是否为 Bar 的子类ret1 = issubclass(Foo, Bar)print(ret1) # 输出12TrueTrue

 

super 

super 是为了解决Python中的多重继承问题,强行去执行父类中的方法

class C1:     def f1(self):        print('c1.f1') class C2(C1):     def f1(self):        # 主动执行父类的 f1 方法        super(C2, self).f1()        print('c2.f1') obj = C2()obj.f1()# 输出:c1.f1c2.f1

利用super在不改变源代码情况添加功能的方法

目录backend  - commons.pyindex.pylib.pysetting.py commons.py >>class Foo:    def f1(self):        print('Foo.f1') index.py >>from setting import ClassNamefrom setting import Path def execute():    model = __import__(Path, fromlist=True)    cls = getattr(model, ClassName)    obj = cls()    obj.f1() if __name__ == '__main__':    execute() setting >># Path = "backend.commons"# ClassName = 'Foo' Path = "lib"ClassName = 'MyFoo' lib >>from backend.commons import Foo class MyFoo(Foo):     def f1(self):        print('before')        super(MyFoo, self).f1()        print('after')这样运行我们自己添加的lib 时结果如下beforeFoo.f1after

 

利用super实现有序字典

class MyDict(dict):     def __init__(self):        self.li = []        super(MyDict, self).__init__()     def __setitem__(self, key, value):        self.li.append(key)        super(MyDict, self).__setitem__(key, value)     def __str__(self):        temp_list = []        for key in self.li:            value = self.get(key)            temp_list.append("'%s':%s" % (key, value))        temp_str = "{" + ",".join(temp_list) + "}"        return temp_str obj = MyDict()obj['k1'] = 123obj['k2'] = 456print(obj) # 输出{'k1':123,'k2':456}

 

单例模式

# 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

class Foo:     instance = None    def __init__(self, name):        self.name = name     @classmethod    def get_instance(cls):        if cls.instance:            return cls.instance        else:            obj = cls('alex')            cls.instance = obj            return obj obj1 = Foo.get_instance()obj2 = Foo.get_instance()print(obj1)print(obj2)# 输出<__main__.Foo object at 0x000001C09B130B70><__main__.Foo object at 0x000001C09B130B70>

 

异常处理

while True:     num1 = input('num1: ')    num2 = input('num2: ')     try:        num1 = int(num1)        num2 = int(num2)        ret = num1 + num2     except Exception as ex:        print(ex)    except ValueError as ex:        print(ex)    except IndexError as ex:        print(ex)

异常处理完整代码

try:    raise Exception('主动错误一下...')    passexcept ValueError as ex:    print(ex)except Exception as ex:    print(ex)else:    passfinally:    pass