内置函数补充

一、isinstance(obj,cls)检查obj是否是类cls的对象

class Foo:
    pass

obj=Foo()

print(isinstance(obj,Foo))      #True

class Bar(Foo):
    pass

print(issubclass(Bar,Foo))      #True

二、__setitem__、__getitem__、__delitem__:只能用字典的方式,才能触发

  与__getattr__、方式不同,效果一样

class Foo:
    def __getitem__(self, item):
        print('getitem')
        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()
print(f1.__dict__)      #{}
f1['name']='alex'       #setitem

print(f1.__dict__)      #{'name': 'alex'}
# print(f1.age)

# del f1.__dict__['name']
# print(f1.__dict__)

f1['name']          #getitem
print(f1['name'])       #getitem    alex


三、str与repr

# class Foo:
#     pass
#
# f1=Foo()
# print(f1)          #<__main__.Foo object at 0x00598FD0>
# print(str(f1))      #<__main__.Foo object at 0x00598FD0>


class Foo:
    def __str__(self):
        return '自定制的对象的显示方式'
    pass

f1=Foo()
print(f1)          #(实际上是在触发__str__内置函数)
#运行结果: 自定制的对象的显示方式    

repr:如果找不到__str__,就会去找__repr__作为替代品

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

    def __repr__(self):
        return '名字是%s,年龄是%s' %(self.name,self.age)

f1=Foo('alex',18)
print(f1)       #repr(f1)---->f1.__repr__()
#运行结果:名字是alex,年龄是18

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

    def __str__(self):
        return '执行str'

    def __repr__(self):
        return '名字是%s,年龄是%s' %(self.name,self.age)

f1=Foo('alex',18)
print(f1)       #执行str

 四、自定制格式化方法

x='{0}{0}{0}'.format('dog')

print(x)            #dogdogdog

class Date:
    def __init__(self,year,mon,day):
        self.year=year
        self.mon=mon
        self.day=day
d1=Date(2016,12,26)

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)                    #20161226
print(y)                    #2016:12:26
print(z)                    #12-26-2016
View Code

 

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
    def __format__(self, format_spec):
        print('我执行啦')
        print('--->',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(2016,12,26)
# format(d1)                #d1.__format__()
# print(format(d1))
print(format(d1,'ymd'))
# 我执行啦
# ---> ymd
# 20161226
print(format(d1,'y:m:d'))
# 我执行啦
# ---> y:m:d
# 2016:12:26
print(format(d1,'m-d-y'))
print(format(d1,'m-d:y'))
print('===========>',format(d1,'asdfas'))
# 我执行啦
# ---> asdfas
# ===========> 20161226
View Code


五、slots属性==>__dict__

1.__slots__是什么:是一个类变量,变量值可以是列表,元组,或可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)

2.为什么使用__slots__:使用点来访问属性本质是在访问类或者对象的__dict__属性字典(类的字典是共享的,而实例的独立的)

          字典会占用大量内存,如果你有一个属性很少的类,但有很多实例,为了节省内存可以使用__slots__取代实例的__dict__

3.缺点:不能添加新的属性,只能使用__slots__定义的属性

 

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

f1=Foo()
f1.name='egon'
print(f1.name)

# f1.age=18       #报错AttributeError: 'Foo' object has no attribute 'age'

#由Foo产生的实例不再具有__dict__属性(因为Foo中定义了__slots__)
# print(f1.__dict__)  #报错:AttributeError: 'Foo' object has no attribute '__dict__'
print(Foo.__slots__)    #name
print(f1.__slots__)     #name
View Code

六、__doc__

class Foo:
    '我是描述信息'
    pass

print(Foo.__doc__)      #我是描述信息
View Code
class Foo:
    '我是描述信息'
    pass

class Bar(Foo):
    pass

print(Bar.__doc__)      #None
该属性无法继承给子类

七、__module__:表示当前操作的对象在哪个模块

__class__:表示当前操作的对象的类是什么

class C:
    def __init__(self):
        self.name='alex'
        
# lib/aa.py
View Code
from lib.aa import C

c1=C()
print(c1.name)              #alex

print(c1.__module__)        #lib.aa
print(c1.__class__)         #<class 'lib.aa.C'>
View Code

八、__del__:析构函数
  当文件执行完毕后或实例被删除后会触发__del__

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

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

f1=Foo('alex')

# del f1.name
# print('----->')
# # ----->
# # 我执行了

del f1
print('----->')
# 我执行了
# ----->
View Code

九、__call__

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

class Foo:
     def __call__(self, *args, **kwargs):
         print('实例执行啦')

f1=Foo()

f1()            #实例执行啦
#实际上触发的是Foo下的__call__
View Code

 

 

 


 

posted @ 2019-03-27 17:06  wind_y  阅读(172)  评论(0编辑  收藏  举报