python学习之路-8 面向对象之进阶

本文深入探讨Python面向对象编程的高级特性,包括封装、继承、多态等核心概念的应用及其实现方式。此外,还详细介绍了类的特殊成员、属性的使用、成员修饰符的作用以及如何实现自定义类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python学习之路-8 面向对象之进阶

上篇内容回顾和补充

  • 面向对象三大特性
    • 封装
    • 继承
    • 多态
      • 在python中没有多态的概念
      • 变量的类型允许为多种数据类型称之为多态
      # c#/java中的多态
      # 伪代码
      def func(int arg):
          print(arg)
      func(123)  # 这样调用是没问题的
      func("aa")  # 这样是会报错的,因为func接受的参数必须是int类型
      
      那么如果func函数中的arg参数需要接受多种类型的参数,就需要按照下面的代码来搞:
      class A:
          pass
      
      class B(A):
          pass
      
      class C(A):
          pass
      
      调用的时候:
      # arg参数,必须是A类型或A的子类类型
      def func(A arg):
          print(arg)
      
      # 下面这三种方式都可以赋值给func函数
      # obj = B()
      # obj = C()
      # obj = A()
      
      func(obj)
      

面向对象中的成员

字段
  • 静态字段(类变量,多个对象共用一个字段,主要用于对象的变量内容都一样的时候)
  • 普通字段(对象变量)
  • 注意:静态字段在代码加载时就被创建了,而普通字段在类被实例化的时候才会被创建
class Foo:
    CC = 123  # 这个被称为字段(静态字段,属于类)
    
    def __init(self):
        self.name = "aaa"  #这个被称为字段(普通字段,属于对象)
  • 静态字段和普通字段的使用
class Province:
    def __init__(self, name):
        self.name = name
        self.country = "中国"
    
# 实例化类
hn = Province("河南")
hn = Province("河北")
hn = Province("山东")
# 比如我需要实例化1000个像上面的对象,
每个对象中都会存在一个self.country="中国"的变量,
这样就会造成内存的浪费,这个时候就需要用静态字段来搞,代码如下:

class Province:
    country = "中国"
    def __init__(self, name):
        self.name = name
    
# 实例化类
hn = Province("河南")
hn = Province("河北")
hn = Province("山东")
# 这样所有的对象就会共用一个类变量country
    
  • 普通字段和静态字段的访问规则
    • 普通字段只能用对象访问
    • 静态字段用类访问(万不得已的时候可以使用对象访问)

方法
  • 普通方法,至少一个self,由对象执行
class Province:
    country = "中国"
    
    def __init__(self, name):
        self.name = name
    
    def show(self): # 普通方法,由对象去调用执行(方法属于类)
        print(self.name)
    
# 调用普通方法
p = Province()  # 实例化成一个对象
p.show()   # 调用对象的show方法
  • 静态方法,使用staticmethod装饰器将该方法变为静态方法,由类直接调用执行(也可以用对象执行,轻易不要用)
class Province:
    country = "中国"
    
    def __init__(self, name):
        self.name = name
    
    @staticmethod
    def show(arg1, arg2):   # 静态方法  == 函数,放在这个位置,表示这个静态方法是跟Province类有关的
        print(arg1, arg2)
    
# 执行静态方法
Province.show(111, 222)
  • 类方法,静态方法的特殊形式,使用classmethod装饰器将该方法变为类方法,由类直接调用执行(也可以用对象执行,轻易不要用)
class Province:
    country = "中国"
    
    def __init__(self, name):
        self.name = name
    
    @classmethod
    def show(cls):  # 类方法,由类调用,最少要有一个参数cls,调用的时候这个参数不用传值,自动将类名赋值给cls
        print(cls)
    
# 调用方法
Province.show()

属性
  • 将类中的方法变为一个属性,该属性的调用方法和字段是一样的
# 使用装饰器 property 将一个方法变为属性,在调用改属性的时候不需要加括号调用,代码如下:
    
class Pager:
    """
    计算分页的功能
    """
    
    def __init__(self, all_count):
        self.all_count = all_count
    
    
    @property
    def all_pager(self):
        """
        计算需要分几页,比如以每页10条为例子
        :return:
        """
        a1, a2 = divmod(self.all_count, 10)
        if a2 == 0:
            return a1
        else:
            return a1 + 1
    
p = Pager(101)
ret = p.all_pager
print(ret)
  • 给属性添加赋值、删除功能(第一种方式)
class Pager:
"""
计算分页的功能
"""

def __init__(self, all_count):
    self.all_count = all_count

@property       # 将一个方法变为属性
def all_pager(self):
    """
    计算需要分几页,比如以每页10条为例子
    :return:
    """
    a1, a2 = divmod(self.all_count, 10)
    if a2 == 0:
        return a1
    else:
        return a1 + 1

@all_pager.setter    # 让all_pager属性具有赋值的方法,提供一个关联方式,具体的创建变量的代码还是需要自己去写的
def all_pager(self, value):
    print(value)
    
@all_pager.deleter   # 让all_pager属性具有删除的方法, 将del和这个方法进行关联,具体的删除方法还是需要自己去写的
def all_pager(self):
    print(“del all_pager”)

p = Pager(101)
ret = p.all_pager
print(ret)
    
p.all_pager = "100" # 给属性设置参数,会调用被装饰器@all_pager.setter装饰的方法
del p.all_pager # 删除  会调用被装饰器all_pager.deleter 装饰的方法
  • 给属性添加赋值、删除功能(第二种方式)
class Pager:
    def __init__(self, all_count):
        self.all_count = all_count

    def f1(self):
        return 123

    def f2(self, value):
        pass

    def f3(self):
        pass

    foo = property(fget=f1, fset=f2, fdel=f3)  # 将foo实例化成一个属性,对foo进行调用的时候执行方法f1,对foo方法进行赋值的时候执行方法f2,对foo进行删除的时候调用方法f3

p = Pager(100)
result = p.foo
print(result)

p.foo = "aaa"

del p.foo

成员修饰符

  • 私有,任何私有的东西都不能够在本类外部进行调用
    • 私有字段
      • 私有普通字段 只能够在本类中调用,被继承的都不能够被调用
      class Foo:
          def __init__(self, name):
              self.__name = name  # 定义一个私有的普通字段
      
          def f1(self):
              print(self.__name)
      
      class Bar(Foo):
          def f2(self):
              print(self.__name)   # 调用不到私有普通字段
      obj = Foo("aaa")
      print(obj.__name)   # 报错,私有字段只能够在本类中的方法进行调用
      obj.f1()    # 这个就是正常的
      • 私有静态字段 # 需要将一个方法变成静态方法,在静态方法中调用静态字段,然后在类外面通过调用类的静态方法,就可以访问类中的静态字段了
      class Foo:
          __cc = "123"        # 定义一个私有的静态字段
      
          def __init__(self, name):
              self.__name = name  
      
          @staticmethod
          def f1():
              print(Foo.__cc)
      
      
      # print(Foo.__cc) # 这样调用会报错
      Foo.f1()  # 这样就可以了
      
    • 私有方法
      • 私有普通方法
      class Foo:
      
          def __init__(self, name):
              self.name = name  # 定义一个私有的普通字段
      
          def __print(self):
              print(self.name)
      
          def f1(self):
              self.__print()
      
      
      obj = Foo("aaa")
      obj.f1()  # 通过调用类中的公有方法来执行私有方法
      
      • 私有静态方法
      class Foo:
      
          def __init__(self, name):
              self.name = name  # 定义一个私有的普通字段
      
          @staticmethod
          def __f2(num):
              print(num)
      
          @staticmethod
          def f3(num):
              Foo.__f2(num)
      
      Foo.f3(10)
  • 私有属性
  • 使用对象访问私有的字段或方法可以通过obj._类名私有方法 调用类中私有的字段和方法
class Foo:

    """
    这是一个测试类
    """

    def __init__(self, name):
        self.name = name
        self.__age = 10

    def __print(self):
        print(self.name)

obj = Foo("xx")
print(obj._Foo__age)
obj._Foo__print()

特殊成员

  • __init__ 构造方法,也叫作初始化方法
  • __del__ 析构函数 垃圾回收
  • __doc__ 注释 对类的一个说明文档
class Foo:

    """
    这是一个测试类
    """

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

obj = Foo("xx")
print(obj.__doc__)

# 输出
    这是一个测试类
  • __class__ 返回该对象属于哪个类 使用方法:对象.__class__
class Foo:

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

obj = Foo("xx")
print(obj.__class__)

# 输出
<class '__main__.Foo'>  # 表示本模块中的Foo类
  • __call__ 执行对象() 会调用__call__方法
class Foo:

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

    def __call__(self):
        print("__call__", self.name)

obj = Foo("xx")
obj()
  • __str__ 直接print对象的时候会调用__str__方法,并且会将__str__方法的返回值赋值给obj进行输出
class Foo:

    """
    这是一个测试类
    """

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

    def __str__(self):
        return self.name

obj = Foo("xx")
print(obj)

# 输出
xx
  • __add__

  • __dict__

class Foo:

    """
    这是一个测试类
    """

    def __init__(self, name, age):
        self.name = name
        self.__age = age

obj1 = Foo("aaa", 100)
obj2 = Foo("bbb", 101)

ret = obj1.__dict__
print(ret)

# 输出
{'_Foo__age': 100, 'name': 'aaa'}
  • __getitem__ 对字典通过key取值和列表通过切片取值底层的实现
    • 字典通过key取值
    class Foo:
    
        def __init__(self, name, age):
            self.name = name
            self.__age = age
    
        def __getitem__(self, item):
            print(item)
    
    
    obj1 = Foo("aaa", 100)
    
    obj1["xxx"]   # 会调用对象obj1的__getitem__方法 中括号内的参数赋值给item
    obj1[1:2]
    
    # 输出
    xxx
    slice(1, 2, None)   # slice是一个类
    • 列表通过切片取值
    
    class Foo:
    
        def __init__(self, name, age):
            self.name = name
            self.__age = age
    
        def __getitem__(self, item):
            print(type(item))
            print(item)
            print(item.start)
            print(item.stop)
            print(item.step)
    
    obj1 = Foo("aaa", 100)
    obj1[1:20:2]
    
    # 输出
    <class 'slice'>
    slice(1, 20, 2)
    1
    20
    2
  • __setitem__ 对字典通过key设置值和列表通过切片设置值底层的实现
    • 字典通过key设置值
    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.__age = age
    
        def __getitem__(self, item):
            print(type(item))
            print(item)
            print(item.start)
            print(item.stop)
            print(item.step)
    
        def __setitem__(self, key, value):
            print(key, value)
    
        def __delitem__(self, key):
            print("del", key)
    
    obj1 = Foo("aaa", 100)
    obj1["key"] = "value"
    
    # 输出
    key value
    • 列表通过切片设置值
    class Foo:
    
        def __init__(self, name, age):
            self.name = name
            self.__age = age
    
        def __getitem__(self, item):
            print(type(item))
            print(item)
            print(item.start)
            print(item.stop)
            print(item.step)
    
        def __setitem__(self, key, value):
            print(key, value)
            print(key.start)
            print(key.stop)
            print(key.step)
    
        def __delitem__(self, key):
            print("del", key)
    
    obj1 = Foo("aaa", 100)
    obj1[1:20] = [1, 2, 3]
    
    # 输出
    slice(1, 20, None) [1, 2, 3]
    1
    20
    None
  • __delitem__ 删除字典指定的key和列表指定的切片范围底层的实现方法
    • 删除字典指定的key
    class Foo:
    
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    
    def __getitem__(self, item):
        print(type(item))
        print(item)
        print(item.start)
        print(item.stop)
        print(item.step)
    
    def __setitem__(self, key, value):
        print(key, value)
        print(key.start)
        print(key.stop)
        print(key.step)
    
    def __delitem__(self, key):
        print("del", key)
    
    obj1 = Foo("aaa", 100)
    del obj1["aaa"]
    
    # 输出
    del aaa
    • 删除列表指定的切片范围
    class Foo:
    
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    
    def __getitem__(self, item):
        print(type(item))
        print(item)
        print(item.start)
        print(item.stop)
        print(item.step)
    
    def __setitem__(self, key, value):
        print(key, value)
        print(key.start)
        print(key.stop)
        print(key.step)
    
    def __delitem__(self, key):
        print("del", key)
        print(key.start)
        print(key.stop)
        print(key.step)
    
    obj1 = Foo("aaa", 100)
    del obj1[1:20]
    
    # 输出
    del slice(1, 20, None)
    1
    20
    None
  • __iter__ 含有该方法,对象就可以被迭代了,默认不可迭代
class Foo:

    def __iter__(self):
        yield 1
        yield 2

obj = Foo()
for item in obj:
    print(item)

面向对象其他

  • isinstance 查看对象是否是类和该类父类的实例

class Foo:
    pass

obj = Foo()

ret = isinstance(obj, Foo)
print(ret)

# 输出
True
  • issubclass 查看前者是否是后者的子类
class Foo:
    pass


class Bar(Foo):
    pass


ret = issubclass(Bar, Foo)
print(ret)

# 输出
Trues
  • 执行父类的方法,在父类方法的基础之上再添加自己的内容
class Foo:

    def f1(self):
        print("Foo.f1")


class Bar(Foo):

    def f1(self):
        # 主动执行父类的f1方法
        super(Bar, self).f1()
        print("哈哈哈")

obj = Bar()
obj.f1()

# 输出
Foo.f1
哈哈哈
  • 应用
    • 自定义类型,对字典进行补充 --> 有序字典
    class MyDict(dict):
    
    def __init__(self):
        self.li = []
        super(MyDict, self).__init__()   # 执行父类的__init__方法
    
    def __setitem__(self, key, value):
        self.li.append(key)
        super(MyDict, self).__setitem__(key, value) # 执行父类的__setitem__方法
    
    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"] = 123    # 调用obj的__setitem__方法
    obj["k2"] = 456
    print(obj)  # 调用obj的__str__方法

异常处理

  • try except
  • else 如果无异常,则执行
  • finally 不管是否有异常,都执行
  • raise 主动触发异常
  • assert 断言 条件成立不报错,反之报错

设计模式之单例模式

单例模式就是一个类只能创建一个实例化对象

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("aaa")
            cls.instance = obj
            return obj

obj1 = Foo.get_instance()
print(obj1)

obj2 = Foo.get_instance()
print(obj2)

# 输出
<__main__.Foo object at 0x1007f9550>
<__main__.Foo object at 0x1007f9550>

posted on 2016-06-26 10:46 奋斗中的码农 阅读(...) 评论(...) 编辑 收藏

标题基于SpringBoot+Vue的社区便民服务平台研究AI更换标题第1章引言介绍社区便民服务平台的研究背景、意义,以及基于SpringBoot+Vue技术的研究现状和创新点。1.1研究背景与意义分析社区便民服务的重要性,以及SpringBoot+Vue技术在平台建设中的优势。1.2国内外研究现状概述国内外在社区便民服务平台方面的发展现状。1.3研究方法与创新点阐述本文采用的研究方法和在SpringBoot+Vue技术应用上的创新之处。第2章相关理论介绍SpringBoot和Vue的相关理论基础,以及它们在社区便民服务平台中的应用。2.1SpringBoot技术概述解释SpringBoot的基本概念、特点及其在便民服务平台中的应用价值。2.2Vue技术概述阐述Vue的核心思想、技术特性及其在前端界面开发中的优势。2.3SpringBoot与Vue的整合应用探讨SpringBoot与Vue如何有效整合,以提升社区便民服务平台的性能。第3章平台需求分析与设计分析社区便民服务平台的需求,并基于SpringBoot+Vue技术进行平台设计。3.1需求分析明确平台需满足的功能需求和性能需求。3.2架构设计设计平台的整体架构,包括前后端分离、模块化设计等思想。3.3数据库设计根据平台需求设计合理的数据库结构,包括数据表、字段等。第4章平台实现与关键技术详细阐述基于SpringBoot+Vue的社区便民服务平台的实现过程及关键技术。4.1后端服务实现使用SpringBoot实现后端服务,包括用户管理、服务管理等核心功能。4.2前端界面实现采用Vue技术实现前端界面,提供友好的用户交互体验。4.3前后端交互技术探讨前后端数据交互的方式,如RESTful API、WebSocket等。第5章平台测试与优化对实现的社区便民服务平台进行全面测试,并针对问题进行优化。5.1测试环境与工具介绍测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值