欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python 面向对象基础和高级复习

程序员文章站 2022-10-08 20:23:56
面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点:逻辑非常复杂 类与对象 对象:属性和方法的集合体 类:一系列相同属性和方法的集合体 现实世界中先有对 ......

面向对象基础

面向对象编程

面向过程编程:类似于工厂的流水线

  • 优点:逻辑清晰
  • 缺点:扩展性差

面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互

  • 优点:扩展性强
  • 缺点:逻辑非常复杂

类与对象

  • 对象:属性和方法的集合体

  • 类:一系列相同属性和方法的集合体

现实世界中先有对象后有类,python中先有类,再实例化出对象

对象的属性的查找顺序

先对象本身-->类-->父类-->父类的父类-->object-->自己定制的元类-->type

给对象定制独有属性

class people:
    pass

p1 = peolple()
p1.name = 'nick'

p2 = people()
p2.name = 'tank'

对象的绑定方法

class people:
    def eat(self):
        print(self, 'eat....')

p1 = peolple()
p1.eat() 
p1.name = 'nick'

p2 = people()
p2.eat()
p2.name = 'tank'

类与数据类型

lis = [1,2,3]  # lis = list([1,2,3])

class foo:
    def __init__(self,name):
        self.name = name

f = foo('name')

lis.append(4)  # 对象调对象绑定的方法,会自动传参
list.append(lis,4)  # 类调用对象绑定的方法,必须得传参

面向对象进阶

类的继承

继承父类,则会有父类的所有属性和方法

class parentclass1():
    pass
    
class parentclass2():
    pass

class subclass(parentclass1,parentclass2):
    pass

类的派生

继承父类的同时自己有init,然后也需要父类的init

class parentclass1():
    def __init__(self,name):
        pass
    

class subclass(parentclass):
    def __init__(self,age):
        # 1. parentclass1.__init__(self,name)
        # 2. super(subclass,self).__init__(name)
        self.age = age  

gll 加: 派生2中

1.不继承,指明道姓访问一个类的函数

2.严格按继承属性查找关系

super()会得到一个特殊的对象,该对象就是专门用来访问父类中属性的(按照继承的关系)

super().__init__(不用为self传值)

super的完整用法是super(自己的类名,self) ,在python2中需要书写完整,在python3中可以简化为super()

类的组合

类对象可以引用/当做参数传入/当做返回值/当做容器元素,类似于函数对象

class parentclass1():
    count = 0
    def __init__(self,name):
        pass

class subclass(parentclass):
    def __init__(self,age):
        self.age = age  

pc = parentclass1()
sc = subclass()

sc.parent_class = pc  # 组合   给对象赋予了属性,属性值为对象
pc.count
sc.parent_class.count  # 0

菱形继承问题

新式类:继承object的类,python3中全是新式类

经典类:没有继承object的类,只有python2中有

在菱形继承的时候,新式类是广度优先(老祖宗最后找);经典类深度优先(一路找到底,再找旁边的)

多态与多态性

一种事物的多种形态,动物-->人/猪/狗

# 多态
import abc

class animal(metaclass=abc.abcmeta):
    @abc.abstractmethod
    def eat():
        print('eat')

class people(animal):
    def eat():
        pass

class pig(animal):
    def eat():
        pass
    def run():
        pass

class dog(animal):  # 报错
    def run():
        pass
        
# 多态性
peo = people()
peo.eat()
peo1 = people()
peo1.eat()
pig = pig()
pig.eat()

def func(obj):
    obj.eat()

class cat(animal):
    def eat():
        pass
cat = cat()

鸭子类型:只要长得像鸭子,叫的像鸭子,游泳像鸭子,就是鸭子.

类的封装

隐藏属性,只有类内部可以访问,类外部不可以访问

class foo():
    __count = 0 
    
    def get_count(self):
        return self.__count
        
f = foo()
f.__count  # 报错
f._foo__count # 不能这样做  实在想用就用  _类名__属性,函数同理

类的property特性

  1. 定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数

  2. 调用时,无需括号

class people():
    def __init__(self,height,weight):
        self.height = height
        self.weight = weight
    
    @property
    def bmi(self):
        return weight/(height**2)
        
    @bmi.setter
    def bmi(self,value)
        print('setter')
        
    @bmi.deleter
    def bmi(self):
        print('delter')

peo = people
peo.bmi

类与对象的绑定方法和非绑定方法

没有任何装饰器装饰的方法就是对象的绑定方法, 类能调用, 但是必须得传参给self

被 @classmethod 装饰器装饰的方法是类的绑定方法,参数写成cls, cls是类本身, 对象也能调用, 参数cls还是类本身

被 @staticmethod 装饰器装饰的方法就是非绑定方法, 就是一个普通的函数

面向对象高级

isinstance,issubclass

isinstance判断是否为类的实例化对象,会检测父类,而type不会检测父类

issubclass,判断是否为其子类

反射

  1. hasattr:通过字符串判断是否类属性存在

  2. getattr:通过字符串获取类属性

  3. setattr:通过字符串修改类属性

  4. delattr:通过字符串删除类属性

gll添加:
应用场景:如何通过sys和getattr获取模块

import time , sys, os
mod = sys.modules['__main__'] # 获取的是当前导入的所有模块对应的总内存地址
print(mod)
tim = getattr(mod, 'time', none)
path = getattr(mod, 'os', none)
print(tim.time())
print(path.path)

call

class foo:
    def __init__(self):
        print('foo()会触发我')
    def __call__(self):
        print('foo()()/f()会触发我')

f = foo()
f()

new

class foo:
    def __new__(self):
        print('new')
        obj = object.__new__(self)
        return obj
    
    def __init__(self):
        print('init')
        
f = foo()

元类

元类用来造类的

元类()-->类-->init

元类()()-->对象--->call

类分为几部分:类名/类体名称空间/父类们

class mymeta(type):
    def __init__(self,class_name,class_bases,class_dic):
        # 控制类的逻辑代码
        super().__init__(class_name,class_bases,class_dic)
    
    def __call__(self,*args,**kwargs):
        # 控制类实例化的参数
        
        obj = self.__new__(self)  # obj就是实例化的对象
        self.__init__(obj,*args,**kwargs)
        print(obj.__dict__)
        
        # 控制类实例化的逻辑
        
        return obj
    
class people(metaclass=mymeta):
    def __init__(self,name,age):
        self.name = name
        self.age = age

单例模式

利用类的绑定方法的特性

name = 'nick'
age = 18

class people():
    
    __instance = none
    
    @classmethod
    def from_conf(cls):
        if cls.__instance:
            return cls.__instance
        
        cls.__instance = cls(name,age)
        return cls.__instance

people.from_conf()

people.from_conf()

利用装饰器

name = 'nick'
age = 18

def deco(cls):
    cls.__instance = cls(name,age)
    
    def wrapper(*args,**kwargs):
        if len(args) == 0 and len(kwargs) == 0:
            return cls.__instance
        
        res = cls(*args,**kwargs)
        return res
    
    return wrapper

@deco
class people():
    def __init__(self,name,age):
        self.name = name
        self.age = age

peo1 = people()

peo2 = people()

利用元类(正宗的)

name = 'nick'
age = 18

class mymeta(type):
    def __init__(self,class_name,class_bases,class_dict):
        super().__init__(class_name,class_bases,class_dict)
        self.__instance = self(name,age)
     
    def __call__(self,*args,**kwargs):
        
        if len(args) == 0 and len(kwargs) == 0:
            return self.__instance
        
        obj = object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        
        return obj
    
class people(metaclass=mymeta):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
peo1 = people()
peo2 = people()

异常处理

捕捉异常

x = 10
y = 20
c = 30

try:
    1/0
except exception as e:
    print(e)

raise

抛出异常

raise keyboardinterrupt('中断捕捉')

assert

判断某一行代码是否有问题