Python面向对象理解

1、封装

将属性方法等内容封装到某类
通过某类调用被封装的内容

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age

# 初始化一个实例时调用__init__方法
tim=Person('Tim',18)
# 将Bob,16分布封装到bob的name和age属性中
bob=Person('Bob',16)

2、继承

  • 对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。Python的类如果继承了多个类,那么其寻找方法的方式(即MRO,method resolution order (方法解析顺序),在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了)有两种,可以分别粗略理解为:深度优先和广度优先。具体实现细节可以看这篇python多重继承C3算法
    • 当类是经典类时,多继承情况下,会按照深度优先方式查找,Python 2.x中默认都是经典类,只有显式继承了object才是新式类。
      
    • 当类是新式类时,多继承情况下,会按照广度优先方式查找Python 3.x中默认都是新式类,不必显式的继承object。
      
  • 继承中super的调用顺序是与MRO-C3的类方法查找顺序一样的,super作用如下:
    • 如果子类继承父类不做初始化,那么会自动继承父类属性。
    • 如果子类继承父类做了初始化,且不调用super初始化父类构造函数,那么子类不会自动继承父类的属性。
    • 如果子类继承父类做了初始化,且调用了super初始化了父类的构造函数,那么子类也会继承父类的属性。
class A:
    def __init__(self):
        print('A')
class B(A):
    def __init__(self):
        print('B')
        super().__init__()
class C(A):
    def __init__(self):
        print('C')
        super().__init__()
class D(B, C):
    def __init__(self):
        print('D')
        super().__init__()

3、多态

Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

4、类成员

leichengyuan.png

4.1.字段
  • 静态字段在内存中只保存一份
  • 普通字段在每个实例对象中都要保存一份
  • 应用场景: 通过类创建实例对象时,如果每个实例对象都具有相同的字段,那么就使用静态字段
class Province:
    # 静态字段
    country = 'China' 
    def __init__(self,name):
        # 普通字段
        self.name = name
obj1 =Province('BeiJing')
print(obj1.name)
print(Province.country)
4.2.方法
  • 普通实例方法:由实例对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的实例对象赋值给self;
  • 类方法:由类调用;至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
  • 静态方法:由类调用;无默认参数;
class Foo:
    def __init__(self,name):
        self.name =name
    # 定义普通实例方法,至少一个self参数
    def ord_func(self):
        print(self.name)
    # 定义类方法,至少一个cls参数
    @classmethod
    def class_func(cls):
        print('类方法')
    # 定义静态方法,无默认参数
    @staticmethod
    def static_fun(): 
        print('静态方法')
f = Foo('ord_func')
f.ord_func()
Foo.class_func()
Foo.static_fun()
4.3.属性
  • 定义时,在普通方法的基础上添加@property装饰器,属性仅有一个self参数,调用时无需括号。@property装饰器可以实现其他语言所拥有的getter,setter和deleter的功能(例如实现获取,设置,删除隐藏的属性);通过@property装饰器可以对属性的取值和赋值加以控制,提高代码的稳定性。
class Goods:
    # 查看属性值 
    @property       
    def price(self):   
        print('@property')
    # 修改、设置属性
    @price.setter                                         
    def price(self, value):       
        print('@price.setter')
    # 删除属性
    @price.deleter   
    def price(self):      
       print('@price.deleter')                             
obj = Goods()
# 自动执行 @property 修饰的 price 方法,并获取方法的返回值 
obj.price
# 自动执行 @price.setter 修饰的 price 方法,并将2000赋值给方法的参数              
obj.price = 2000 
# 自动执行 @price.deleter 修饰的 price 方法  
del obj.price     

5、类成员的修饰符

  • _xxx 表示这是一个保护成员(属性或者方法),它不能用from module import * 导入,其他方面和公有一样访问;
  • __xxx 这表示这是一个私有成员,它无法直接像公有成员一样随便访问,但可以通过实例对象名._类名__xxx这样的方式可以访问;
  • xxx__表示这是一个特殊成员,用来区别其他用户自定义的命名以防冲突,就是例如__init()、 del() 这些特殊方法

6、类的特殊成员

魔法函数.png

  1. __doc __输出类的描述信息
  2. __module __输出当前操作对象所在模块
  3. __class __输出当前操作对象的类
  4. __init __构造方法,通过类创建实例对象时,自动触发执行
  5. __del __析构方法,当对象在内存中被释放时,自动触发执行,此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
  6. __call__对象后面加括号,触发执行,构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo:
    def __init__(self):
        pass
    def __call__(self,*args,**kwargs):
        print('__call__')
# 执行 __init__
obj6 = Foo() 
# 执行 __call__
obj6()
  1. __dict__类或对象中的所有成员
class Province:
    country = 'China'
    def __init__(self, name, count):
        self.name = name
        self.count = count
    def func(self, *args, **kwargs):
        print('func')
# 获取类的成员,即:静态字段、方法、
# 输出:{'__module__': '__main__', 'country': 'China', '__init__': <function Province.__init__ at 0x00000264B20F1E18>, 
# 'func': <function Province.func at 0x00000264B4638D08>, '__dict__': <attribute '__dict__' of 'Province' objects>, 
# '__weakref__': <attribute '__weakref__' of 'Province' objects>, '__doc__': None}
print(Province.__dict__)
# 输出:{'name': 'HeBei', 'count': 1000}
obj1 = Province('HeBei',1000)
print(obj1.__dict__)
obj2 = Province('HeNan', 3)
# 输出:{'name': 'HeNan', 'count': 3}
print(obj2.__dict__)
  1. __str__如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。
class Foo:
    def __init__(self):
        pass
    def __str__(self):
        return '__str__'
obj=Foo()
print(obj)
  1. getitemsetitem、__delitem__用于索引操作,如字典。以上分别表示获取、设置、删除数据。
  2. getslicesetslice、__delslice__该三个方法用于分片操作,如列表。
  3. __iter__用于迭代器,之所以列表、字典、元组可以进行for循环。
  4. new__和__init new__是一个静态方法,而__init__是一个实例方法,new__方法会返回一个创建的实例,而__init__什么都不返回,当创建一个新实例时调用__new,初始化一个实例时用__init
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值