Python: 学习系列之六:对象的内置函数及类对象的特殊方法

系列

issubclass()与isinstance() 判断类对象与类对象或实例的关系

class ParentClass(object):
    pass


class ChildClass(ParentClass):
    pass


class ThirdClass(object):
    pass


# issubclass判断类对象与类对象的关系
print(issubclass(ChildClass, ParentClass))  # True
print(issubclass(ChildClass, (ParentClass, ThirdClass)))  # True,后面是个元组,只要满足元组内任意一个父类就为True

# isinstance判断实例对象与类对象的关系
c = ChildClass()
print(isinstance(c, ChildClass))  # True
print(isinstance(c, (ChildClass, ParentClass, ThirdClass)))  # True,后面是个元组,只要满足元组内任意一个类就为True

type()获取指定对象的类型

print(type(c)) #<class '__main__.ChildClass'>,获取指定对象的类型
print(type(ChildClass)) #<class 'type'>, 类对象的类型是type

dir()获取对象的所有信息和__dict__获取对象自定义信息

class MyClass(object):
    def __init__(self):
        self.name = 'cong'

    @classmethod
    def cm(cls):
        pass

    @staticmethod
    def sm(p1):
        print(p1)


#  获取所有属性和方法,类对象结果中不包含实例属性
print(dir(MyClass))  # [...'__subclasshook__', '__weakref__', 'cm'] 获取所有属性和方法

# 获取所有属性和方法, ['__subclasshook__','__weakref__', 'cm', 'name', 'sm']]
print(dir(MyClass()))

# 获取自定义属性和方法
# {'cm': <classmethod object at 0x000002266E1B5710>, 'sm': <staticmethod object at 0x000002266E1B5748>}
print(MyClass.__dict__)
# 获取自定义属性和方法
print(MyClass().__dict__)  # {'name': 'cong'}

反射(hasattr,getattr,setattr,delattr)

"""
    用于反射,当不知道对象属性或方法的情况下适用
    1. hasattr(object,name) 用于判断对象是否有指定的属性或方法
    2. getattr(object,name[,default]) 用于获取指定属性的值或方法,getattr(object,name)等价于object.name
    3. setattr(object,name,value) 给对象添加或修改指定属性的值或方法,setattr(object,name,value)等价于object.name=value
    4. delattr(object,name) 用于删除指定的属性或方法,等价于del object.name
"""


class MyClass(object):
    def __init__(self):
        self.x = 1

    def do_sth(self):
        print('do_sth has been called')


mc = MyClass()
# hasattr 用于判断对象是否有指定的属性或方法
print(hasattr(mc, 'x'))  # True

print(hasattr(mc, 'do_sth'))  # True
print(hasattr(mc, 'Y'))  # False

print(getattr(mc, 'x'))  # 1
print(getattr(mc, 'Y', 2))  # 2
# <bound method MyClass.do_sth of <__main__.MyClass object at 0x0000020B74C06668>>
print(getattr(mc, 'do_sth'))

# 方法获取后,这里可以直接调用
f = getattr(mc, 'do_sth')
f()  # do_sth has been called

setattr(mc, 'x', 6)
print(mc.x)  # 6
print(getattr(mc,'x'))  # 6


delattr(mc,'x')
print(hasattr(mc, 'x'))  # False

len()返回对象的长度 及__len__()

print(len('abc'))  # 3
print(len([1, 2, 3]))  # 3
print(len((1, 2, 3)))  # 3
print(len({'a': 1, 'b': 2, 'c': 3}))  # 3


class MyClass(object):
    def __len__(self):
        return 18


# 只有实现了__len__方法的自定义对象,才能使用len(MyClass())就会报错
print(len(MyClass()))  # 18

__iter()和__next() 自定义迭代器

"""
    自定义迭代器,如果想让for-in语句可以用于自定义类对象的实例对象,必须要实现__iter__()和__next()这两个方法。
    for-in语句会首先调用__iter_()返回一个可迭代的对象,然后不断调用__next__()返回下一次迭代的值,直到抛出StopIteration时退出循环
"""


class MyClass(object):
    def __init__(self):
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.i > 5:
            raise StopIteration()
        else:
            self.i += 1
            return self.i


for key in MyClass():
    print(key)  # 1,2,3,4,5,6

__add__()和__radd__() 让两个对象相加,即obj1+obj2

"""
    1. + 对应的特殊方法是__add__()和__radd__()
    2. - 对应的特殊方法是__sub__()和__rsub__()
    3. * 对应的特殊方法是__mul__()和__rmul__()
    4. / 对应的特殊方法是__truediv__()和__rtruediv__()
    5. // 对应的特殊方法是__floordiv__()和__rfloordiv__()
"""


class MyClass1(object):
    def __add__(self, other):
        print('add have been called')
        return 'x' + other


class MyClass2(object):
    def __radd__(self, other):
        print('radd have been called')
        return other+'y'


# add have been called
# radd have been called
# xy
print(MyClass1()+MyClass2())

__str__() 和__repr()都返回对象的字符串表示

class MyClass(object):
    def __str__(self):
        return 'x'

    def __repr__(self):
        return 'y'


print(str(MyClass()))  # x
print(repr(MyClass()))  # y

# hello
# world
print(str('hello \n world'))  # 这是给用户看的
print(repr('hello \n world'))  # 'hello \n world', 这是给程序员看的,主要用于调试用的

__new__() 创建实例对象

"""
    当使用"类名([实参])"创建实例对象时,python解析器的主要处理过程包括两步:
    1. 调用特殊方法__new__()创建实例对象
    2. 调用特殊方法__init__()对对象的实例进行初始化

    如果__new__()没有定义,就会调用父类中的__new__(),直到找到object中的__new__().
"""


class ParentClass(object):
    def __new__(cls):
        obj = super().__new__(cls)
        print("the object has been created , the id is %s" % id(obj))
        return obj


class ChildClass(ParentClass):
    def __init__(self):
        print("the object has been initialize, the id is %s" % id(self))


# the object has been created, the id is 1897583171176
# the object has been initialize, the id is 1897583171176
c = ChildClass()

# 从上可以看出,它的id是一样的,c这个实例对象实例上是由object中的__new__()方式来创建的。

__del__() 对象被销毁之前,会自动调用__del__()来执行一些额外的清理工作

"""
    对象被销毁之前,会自动调用__del__()来执行一些额外的清理工作
    当对象的引用计数为0时,对象并不会被立即回收,何时收回并不确定
"""
class MyClass(object):
    def __del__(self):
        print('the object will be deleted!')


mc = MyClass()
del mc  # the object will be deleted!

__getattribute__() 避免指定的属性或方法不存在时抛出AttributeError,可以使用__getattr__()或__getattribute__()

"""
    当访问实例对象的属性或方法时,如果指定的属性或方法不存在时,就分抛出AttributeError.
    为了避免指定的属性或方法不存时抛出如上错误,可以使用__getattribute__()或者__getattr__()
"""
class MyClass(object):
    def __getattribute__(self,name):
        if name == "data":
            return 18
        else:
            raise AttributeError("Not Found")

mc = MyClass()
print(mc.data)

__getitem__() ,__setitem__(),delitem__()让实例可以实现类似这样的功能o=obj[key], obj[key]=value或del obj[key]

class MyClass(object):
    def __init__(self):
        self.data = {}

    def __getitem__(self, key):
        return self.data[key]

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

    def __delitem__(self, key):
        del self.data[key]


mc = MyClass()
mc['name'] = 'cong'
mc['age'] = 18
print(mc.data)   # {'name': 'cong', 'age': 18}
print(mc.data['name'])  # cong
del mc['age']
print(mc.data)  # {'name': 'cong'}

__call__() 可以像调用函数一样调用实例

class MyClass(object):
    def __call__(self, *args, **kwargs):
        print(args, kwargs)


mc = MyClass()
mc()  # () {}
mc(1, 2, x=3, y=4) #(1, 2) {'x': 3, 'y': 4}

print(callable(print)) #True
print(callable(mc))  # True

特殊属性__doc__,用于表示类对象的文档字符串

def test():
    """This is a test document string.

    This is the detailed information
    """
    pass



print(test.__doc__)  # This is a test document string.

# Help on function test in module __main__:
# test()
# This is a test document string
# None
print(help(test))

特殊属性__slots__ 可以动态绑定属性和方法


"""
    默认情况下,访问实例对象的属性是通过访问特殊属性__dict__来实现的,比如:访问obj.x 其实是访问obj.__dict__['x']
    当在对象中定义了特殊属性__slots__后,其实对象就不再创建特殊属性__dict__, #AttributeError: 'MyClass' object has no attribute '__dict__'
    __slots__只对当前对象起作用,对其子类是不起作用的,如果子类中也定义了__slots__,它子类动态绑定的内容为子类的slots+父类的slots
"""

from types import MethodType


class MyClass(object):
    # 这里可以赋值一个所有元素都是字符串的数组或元组
    __slots__ = ("attr1", "do_sth1")


mc = MyClass()
mc.attr1 = 20
# mc.att2 = 23  # AttributeError: 'MyClass' object has no attribute 'att2'


def do_sth1(self):
    print('do_sth1 has been called')


mc.do_sth1 = MethodType(do_sth1, mc)

mc.do_sth1()  # do_sth1 has been called

print(mc.__dict__)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值