Python学习记录(十五):面向对象进阶

Python学习记录(十五):面向对象进阶

instance

是否是实例

class Foo:
    pass

f1 = Foo()
print(isinstance(f1,Foo))	# True

issubclass

是否是子类

class Foo:
    pass

class Bar(Foo):
    pass

print(issubclass(Bar,Foo))	# True

getattribute

无论是否存在该属性,都执行

# __getattribute__优先级更高
class Foo:
    def __init__(self,x):
        self.x=x

    def __getattr__(self, item):
        print('执行的是getattr')
        
    def __getattribute__(self, item):
        print('执行的是getattribute')

f1=Foo(10)
# 抛出异常时,才执行__getattr__
f1.xxxxxx 
# 执行的是getattribute
# 模拟getattribute的默认情况
class Foo:
    def __init__(self,x):
        self.x=x

    def __getattr__(self, item):
        print('执行的是getattr')
        
    def __getattribute__(self, item):
        print('执行的是getattribute')
        raise AttributeError('抛出异常了')

f1=Foo(10)
# 抛出异常时,才执行__getattr__
f1.xxxxxx 
# 执行的是getattribute
# 执行的是getattr

getitem、setitem和delitem

与getattr、setattr和delattr的区别在于item系列需要对字典操作才能生效

class Foo:
    def __getitem__(self, item):
        print('getitem',item)
        return self.__dict__[item]

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

    def __delitem__(self, key):
        print('delitem')
        self.__dict__.pop(key)

f1=Foo()

# setitem
f1['name']='bill'
f1['age']=18

# delitem
del f1['age']

# getitem
print(f1['name'])

str和repr

用于改变对象的字符串显示

str函数或print函数是执行obj.str()

repr函数或者交互式解释器Console是执行obj.repr()

# 默认情况下打印对象
class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age

f1=Foo('egon',18)
print(f1) 
# 返回类名和内存地址
# <__main__.Foo object at 0x00000269FC43C740>
# 使用__str__修改输出字符串显示
class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '名字是%s 年龄是%s' %(self.name,self.age)

f1=Foo('egon',18)
# 三种不同的调用方式
print(f1)        # 名字是egon 年龄是18

x=str(f1)
print(x)         # 名字是egon 年龄是18

y=f1.__str__()
print(y)         # 名字是egon 年龄是18
# 使用__repr__修改输出字符串显示
class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return 'str输出'
    def __repr__(self):
        return 'repr输出'

f1=Foo('egon',19)
# 若在交互式解释器Console里输入f1,也默认是repr
print(repr(f1))     # repr输出
print(str(f1))      # str输出
print(f1)           # str输出

自定义格式化format

# 默认的字符串格式化
class Date:
    def __init__(self,year,mon,day):
        self.year=year
        self.mon=mon
        self.day=day
d1=Date(2024,7,20)
# 0表示是元组的第0个元素,即d1对象本身
x='{0.year}{0.mon}{0.day}'.format(d1)
y='{0.year}:{0.mon}:{0.day}'.format(d1)
z='{0.mon}-{0.day}-{0.year}'.format(d1)
print(x)	# 2024720
print(y)	# 2024:7:20
print(z)	# 7-20-2024
# 自定义输出日期的格式化

# 定义三种不同的格式
format_dic={
    'ymd':'{0.year}{0.mon}{0.day}',
    'm-d-y':'{0.mon}-{0.day}-{0.year}',
    'y:m:d':'{0.year}:{0.mon}:{0.day}'
}

class Date:
    def __init__(self,year,mon,day):
        self.year=year
        self.mon=mon
        self.day=day
    # format_spec表示格式化的结构
    def __format__(self, format_spec):
        # 不输入格式或输入错误都按照默认格式
        if not format_spec or format_spec not in format_dic:
            format_spec='ymd'
        fm=format_dic[format_spec]
        return fm.format(self)
    
d1=Date(2024,7,20)
print(format(d1,'ymd'))      # 2024720
print(format(d1,'y:m:d'))    # 2024:7:20
print(format(d1,'m-d-y'))    # 7-20-2024
# 不输入格式或输入错误都按照默认格式
print(format(d1))            # 2024720
print(format(d1,'xxxxxxx'))  # 2024720

slots

__silots__是一个类变量,变量值可以是列表、元组或者可迭代对象,也可以是字符串。意味着所有实例只有一个数据属性。目的是节省内存,使得实例没有dict属性字典。假设一个类的数据属性不多,但有很多个实例,会导致生成多个dict属性字典,字典占用的内存空间大

class Foo:
    __slots__=['name','age']  

f1=Foo()
f1.name='bill'
f1.age=18
# 不能添加slots列表里没有的属性,也不能删除,因为没有dict字典,删除本身就是基于dict字典的操作
f1.gender='male'
del f1.age

print(f1.__dict__)       # 报错:没有dict字典
print(Foo.__slots__)     # ['name', 'age']
print(f1.__slots__)      # ['name', 'age']

call

定义了__call__方法的对象称为可调用对象,即该对象可以像函数一样被调用

class CallabeClass:
    # 重载功能
    def __call__(self):
        print('CallabeObj')
        
CallabeObj = CallabeClass()
# 直接调用,如同调用函数一般
CallabeObj()
# CallabeObj
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值