面向对象(三)

本文详细探讨了Python中的面向对象特性,包括`isinstance`和`issubclass`的使用,反射机制如`getattr`、`hasattr`和`setattr`,以及`__str__`、`__repr__`和`__del__`等特殊方法。此外,还讲解了`__new__`在实现单例设计模式中的作用,`__call__`、`__len__`、`__hash__`和`__eq__`的相关操作,并提供了一个巧妙的示例来说明这些概念。

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

目录:

  • isinstance和issubclass
  • 反射
    • getattr
    • hasattr
    • setattr
    • delattr
  • __str__和__repr__
  • __del__
  • item系列:
    • __getitem__
    • __delitem__
    • __setitem__
  • __new__(单例设计模式)
  • __call__
  • __len__
  • __hash__
  • __eq__

isinstance和issubclass

isinstance(obj, cls):返回True和False 判断obj是否属于cls这个类。

class A:
    a = 'dddd'
    def __init__(self, name, age):
        self.name = name
        self.age = age

class B(A):
    pass


a = B('我是a', 'none')
print(isinstance(a, B))
print(isinstance(a, A))
输出结果:
True
True

可以看到子类实例化的对象也是属于父类的

issubclass(sub, super)检查sub类是否是 super 类的派生类

class Foo(object):
    pass

class Bar(Foo):
    pass

issubclass(Bar, Foo)
输出结果为:
True

object是所有类的父类

反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

class A:
    a = 'dddd'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def tell(self):
        print('telling')

'判断是否有该属性'
print(hasattr(A, 'tell'))

a = A('我是a', 'none')

'拿到属性'
t = getattr(a, 'tell')
'设置属性'
setattr(a, 'sex', '男')

'删除属性'
delattr(a, 'sex')

我们可以将hasattr和getattr一起使用:

class A:pass

com = input('请输入指令:')
if hasattr(A, com):
    ret = getattr(A, com)
    ret()

可以用作判断使用。
本模块的导入

import sys
def s1():
    print('s1')

def s2():
    print('s2')

hasattr(sys.modules[__name__], s1)
getattr(sys.modules[__name__], s2)

__str__和__repr__

format_str = {
    'net':'{obj.name} - {obj.age}',
    'ten':'{obj.name} * {obj.age}',
    'nte':'{obj.name} + {obj.age}'
}

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

    def __repr__(self):
        return self.name

    def __str__(self):
        return self.name

    def __format__(self, format_spec):
        if not format_spec or format_spec not in format_str:
            format_spec = 'net'
        fmt = format_str[format_spec]
        return fmt.format(obj=self)


a = A('stay', 20)
print('%r'%a)
print('%s'%a)
print(format(a, 'net'))

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class Foo:

    def __del__(self):
        print('执行我啦')

f1=Foo()
del f1
print('------->')

#输出结果
执行我啦
------->

先执行__del__方法再删除

item系列

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

    def __getitem__(self, item):
        return self.__dict__[item]

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):  # 只有对对象像字典一样操作时才会条用item系列方法
        print('删除obj[key]执行')  # ******
        self.__dict__.pop(key)

    def __delattr__(self, item):  #对对象用对象.的方式进行调用时会调用
        print('删除obj.key执行')   # *****
        self.__dict__.pop(item)

a = A('我是A')
a['age'] = 11
a['sex'] = '男'
print(a.age)
print(a['sex'])
del a.age
del a['sex']

__new__

单例设计模式:

class A:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = object.__new__(cls)
        return cls._instance

a = A()
b = A()
print(id(a), id(b))

单例设计模式的四种实现方式

__call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:

    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):

        print('__call__')


obj = Foo() # 执行 __init__
obj()       # 执行 __call__

__len__

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))

__hash__

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a)

__eq__

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)

一个比较牛逼的例子

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

    def __hash__(self):
        return hash(self.name+self.sex)

    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:return True


p_lst = []
for i in range(84):
    p_lst.append(Person('egon',i,'male'))

print(p_lst)
print(set(p_lst))

感觉这重写的方式和java的差不多都是重写hash和eq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值