python面向对象简单整理

1. 面向对象三大特性

  • 封装

    • 归类,将函数放置到一个类中
    • 打包, 将数据打包到一个对象中,限制范围
  • 继承

    • 多个类有相似功能时
  • 多态

    • python原生支持多态,崇尚鸭子模型,由于python函数传参时,无需指定类型
def func(arg):  # arg可以接受多种类型,只需要其中有send方法即可(实现了其他语言的接口功能)
  arg.send()

2. 类成员

  • 1.类的成员
# 定义一个基类
class Base(object):

    def func(self):
        print(123) 


# 子类 继承 基类
class Foo(Base):
    country = "中国"  # 类变量/静态字段
    

    def __init__(self,name):
        self.name = name  # 实例变量/字段
        self.__salary = 2000  # 实例化的外部不能访问
    
    # 实力方法
    def func(self):
        print(Foo.country)  # 推荐是用类名+变量名
        print(self.country) 
        
        # 调用类的成员
        Base.func(self)
        super.func(self)  # 推荐使用
        
    # 静态方法  建议是用类调用 Foo.salary()
    # 如果方法中无需使用对象中封装的自己的变量
    @staticmethod
    def salary(self):  # 私有变量  外部使用函数访问
        return self.__salary
        
    
    # 类方法
    # 调用 Foo.show(1,2)
    # 什么时候写: 如果该方法中使用了当前类的方法或者变量的时候写类方法  
    @classmethod
    def show(cls,x1,x2):
        print("类方法",cls.salary())
     
    # 私有实例方法   
    def __display(self,arg):
        print(arg)
    
    # 私有静态方法 
    @staticmethod
    def __display1(arg):
        print(arg)
    
    # 私有类方法 
    @classmethod
    def __display2(cls,arg):
        print(arg)
    
    # 方法包装访问私有方法
    def func(self):
        self.__display("123")
        Foo.__display1(456)
        Foo.__display2(789)
    
    # 属性  无法加参数
    # 使用  obj.start  不用加括号, 有返回值
    # 共有私有 属性  __start
    @property   
    def start(self):
        return 1
        
   
Foo.country
obj = Foo("Jeecy")  # Foo类的对象/实例

  • 分为三类

    • 实例变量(字段)
    • 类变量(静态字段)
    • 私有变量
  • 方法

    • 实例方法
    • 静态方法 @staticmethod
    • 类方法 @classmethod
    • 私有方法: 内部才能访问
  • 静态方法和类方法和实力方法的区别?

    • 定义不一样 装饰器一不一样
    • 调用不一样 obj.func() cls.func
    • 类方法 为了不想写当前类名,使用类方法 cls
  • 属性: 方法构造出来的

    • 使用 @property 修饰
    • 无法加参数
    • 使用 obj.start 不用加括号, 有返回值
    • 共有私有 属性 __start
  • 主动调用其它类成员的方法

        Base.func(self)
        super.func(self)  # 推荐使用
    

类的内置魔术方法


class Foo(object):
    # 在类生成之前自动调用的方法,多用于单例模式
    def __new__(cls, *args, **kwargs):
        
        return object.__new__(cls)  # 创建一个当前类的对象(内部时空的)
    
  # 类的构造方法, 在类实例化成对象的时候自动执行的方法
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    # obj()  对象加()  自动调用 __call__方法
    def __call__(self, *args, **kwargs):
        # 打印接受值
        print(*args, **kwargs)
        # 返回一个值
        return 6
    
    
    # obj["yu"]  对象加['item'] 调用  __getItem__方法
    def __getitem__(self, item):
        # 打印接受值
        print(item)
        # 返回值
        return 666
    
    
    # obj["key"] = value 调用 __setItem__ 方法  无返回值
    def __setitem__(self, key, value):
        print(key,value)
        
    # del obj["key"]  调用 __delitem__ 方法  没有返回值
    def __delitem__(self, key):
        print(key)
        
    
    # obj + obj   
    def __add__(self, other):
        print(self.age + object.age)
        
        return 888
        
    
    # with obj as f:  就要执行  如果有返回值就  as f 接受
    def __enter__(self):
        print('111')
        return 6
    
    # with 执行完内部代码后要执行的内容
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('222')
        
    # 直接打印这个类或者对象的时候显示的内容
    def __str__(self):
        return self.name
        
    # 类的注释
    # 无需定义
    #def __doc__(self):
        #pass
    
    # 获取对象封装的数据
    # 无需定义  
    # def __dict__(self):
        # pass
    
    # 使对象便可的迭代  返回一个迭代器
    def __iter__(self):
        return iter(11,22,33,44,55,66)
        





  • 特殊成员
    • def __init__(self)

    • def __new__(cls)

    • obj() 对象加括号会调用 下面call方法
      def __call__(self,*args,**kwargs)

    • obj[] 自动执行 __gitItem__(self,item)

def __getItem(self,item):
  print(item)
  return 6
  • issubclass
    issubclass(Foo,Base) Foo 是不是 Base的子子孙孙类
  • type
    from types import MethodType,FunctionType
    type(obj) == Foo obj是不是 Foo的实例
  • isinstance
    isinstance(obj,Foo) 对象 是不是 类/基类的 实例

使用类写一个分页

class Pagenation(object):
    def __init__(self, data_list, page, per_page_num=10):
        '''
        初始化
        :param data_list: 数据源
        :param page: 当前要查看的页码数
        :param per_page_num: 每页要显示的页码数
        '''
        self.data_list = data_list
        self.page = page
        self.per_page_num = per_page_num

    @property
    def start(self):
        '''
        起始条数索引
        :return:
        '''
        return (self.page - 1) * self.per_page_num

    @property
    def end(self):
        '''
        结束条数索引
        :return:
        '''
        return self.page * self.per_page_num

    def show(self):
        page_data_list = data_list[self.start:self.end]

        for item in page_data_list:
            print(item)


# 数据源
data_list = []

for i in range(1, 901):
    data_list.append(f"Jack-{i}")

while True:
    page = int(input("请输入要查看的页码数:"))
    obj = Pagenation(data_list, page)  # 实例化一个分页
    obj.show()  # 展示

方法 和 函数的区分

  • 类 -> 方法
  • 函数 - 函数

反射

hasattr(handler,val)  # 有没有这个属性

f = getattr(handler,val)  # 根据字符串为参数,去模块/类/对象中寻找与之同名的成员


class Foo(object):
    pass

setattr(Foo,'x2',"sdfasdfa")  # 添加变量

setattr(Foo,"xx",lambda x:x+1) # 添加方法

a = getattr(Foo,"xx")
print(a(2))

判断一个 arg() arg是否能被调用

callable(arg) 返回 True False

类的约束

class BaseMessage(object):
    
    def send(self):
        raise NotImplementedError("send() 必须被重写")
        
# 约束  派生类必须重写父类方法 有几个参数  子类也需要有几个参数
  • 抽象类 抽象方法
from abc import ABCMeta,abstractmethod

class Base(metaclass=ABCMeta):
  
    @abstractmethod
    def f2(self):  # 抽象方法
        pass
  • 抽象类 和抽象方法 子类必须重写 来实现这个方法
  • 接口: 易中数据类型 用于约束派生类中必须实现指定的方法
    python中不存在,java和c#中是存在的
    python中使用抽象类和抽象方法:编写麻烦 或者 认为的主动抛出异常
    抛出的异常是 raise NotImplementedError("send() 必须被重写")

自定义异常


import os
class ExistsError(Exception):
    def __init__(self,code,message):
        self.code = code
        self.message = message

class KeyInvalidError(Exception):
    def __init__(self,code,message):
        self.code = code
        self.message = message

def func(path,prev):
    """
    去 path路径中的文件中 找到前缀为prev的一行数据,获取数据并返回给调用者
    1000 成功
    1001 文件不存在
    1002 关键字为空
    1003 未知错误
    :param path: 文件路径
    :param prev: 关键字
    :return: response
    """
    response = {
        "code": 1000,
        "data":None
    }
    try:
        if not os.path.exists(path):
            raise ExistsError(1001,"文件不存在")
        if not prev:
            raise KeyInvalidError(1002,"关键字为空")

    except ExistsError as e:
        response["code"] = e.code
        response["data"] = e.message
    except KeyInvalidError as e:
        response["code"] = e.code
        response["data"] = e.message
    except Exception as e:
        response["code"] = 1003
        response["data"] = "未知错误"
    return response

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354