__str__和__repr__
class Dog: def __init__(self,name,age): self.name=name self.age=age def __str__(self): return '%swangwangwang'%self.name def __repr__(self): return 'hahaha' def func(self): return 'hehehe' d=Dog('TEDDY',5) str(d) print(str(d)) print(d.__repr__()) print(d.func()) str函数或者print函数--->obj.__str__() repr或者交互式解释器--->obj.__repr__() 如果__str__没有被定义,那么就会使用__repr__来代替输出 即__repr__相当于是__str__的备胎 注意:这俩方法的返回值必须是字符串,否则抛出异常
除了以上双下方法调用,还有另外一个种调用方式%+字母
class B: def __str__(self): return 'str : class B' def __repr__(self): return 'repr : class B' b = B() print('%s' % b) #%s 代表str print('%r' % b) #%r 代表repr
析构方法 __del__
class Animal(object):
# 初始化方法
#创建完对象后会自动被调用
def __init__(self, name):
print('__init__方法被调用')
self.name = name
print('%s方法被调用'%self.name)
# 析构方法 --------析构函数时解释器自动触发的 ,不是del方法调用的
# 当对象被删除时,会自动被调用
def __del__(self):
print("__del__方法被调用")
print("%s对象马上被干掉了..." % self.name)
# 创建对象
dog = Animal("哈皮狗")
# 删除对象
del dog
__init__方法被调用
哈皮狗方法被调用
__del__方法被调用了
哈皮狗对象马上被干掉了
items
# class Foo: # def __init__(self,name,age,sex): # self.name = name # self.age = age # self.sex = sex # # def __getitem__(self, item): # if hasattr(self,item): # return self.__dict__[item] #这里将对象字典化了,__getitem__可以通过字典的方法对对象进行操作,也可以将对象列表化 item=[] 通过下标操作 # # def __setitem__(self, key, value): # self.__dict__[key] = value # # def __delitem__(self, key): # del self.__dict__[key]
#
# f=Foo('张三',20,'男')
# print(f['name']) ===f.name
# f['job']=‘学生’ #添加功能 这里调用了 __setitem__ 方法
# del f['job'] #删除功能 这里调用了 __delitem__ 方法
__new__(创建对象)和__init__的对比:
1、继承自object的新式类才有__new__
2、__new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
3、__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例
4、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
5、如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,;那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。
class A: # def __init__(self): # self.x = 1 # print('in init function') # def __new__(cls, *args, **kwargs): # print('in new function') # return object.__new__(cls, *args, **kwargs) # # a1 = A() # a2 = A() # a3 = A() # print(a1) # print(a2) # print(a3) # print(a1.x)
in new function #首先是__new__执行创建对象,然后才是__init__调用
in init function
in new function
in init function
in new function
in init function
<__main__.A object at 0x00000000028A6C18>
<__main__.A object at 0x00000000028A6BE0>
<__main__.A object at 0x00000000028A6C88>
1
单例模式
__new__方法通常会被用到单例模式中,所谓单例模式就是一个类只产生一个实例,且后边的会覆盖前面产生的。
class A: # __instance = None # def __init__(self,name,age): # self.name = name # self.age = age # def __new__(cls, *args, **kwargs): # if cls.__instance: # return cls.__instance # cls.__instance = object.__new__(cls) # return cls.__instance # # person1 = A('张三',38) # person2 = A('李四',25) # print(person1 ) # print(person2 ) # print(person1 .name) # print(person2 .name)
<__main__.A object at 0x0000000002917710>
<__main__.A object at 0x0000000002917710>
李四
李四
__hash__和__eq__
__hash__和hash()是一样的,如果输入的参数是可哈希的,则得到一串数字,如果不可哈希则报错。
print(hash('abc')) # 4230684475629810636 print(hash('a')) # 562753921365209871 print(hash(2)) # 2 print(hash[1,2,3]) #报错 因为列表是不可哈希的
# class A: # def __init__(self,name,sex,age): # self.name = name # self.sex = sex # self.age = age # # def __eq__(self, other): # if self.name == other.name and self.sex == other.sex: # return True # return False # # def __hash__(self): # return hash(self.name) # # a = A('张三','男',38) # b = A('张三','男',37) # print(set((a,b)))
__getattr__、__call__、__setattr__
class Dict(dict): ''' 通过使用__setattr__,__getattr__,__delattr__ 可以重写dict,使之通过“.”调用 ''' def __setattr__(self, key, value): print("In '__setattr__") self[key] = value def __getattr__(self, key): #当调用不存在的属性时访问这个方法 try: print("In '__getattr__") return self[key] except KeyError as k: return None def __delattr__(self, key): try: del self[key] except KeyError as k: return None # __call__方法用于实例自身的调用,达到()调用的效果 def __call__(self, key): # 带参数key的__call__方法 try: print("In '__call__'") return self[key] except KeyError as k: return "In '__call__' error" s = Dict() print(s.__dict__) # {} s.name = "hello" # 调用__setattr__ # In '__setattr__ print(s.__dict__) # 由于调用的'__getattr__', name属性没有加入实例属性字典中。 # {} print(s("name")) # 调用__call__ # In '__call__' # hello print(s["name"]) # dict默认行为 # hello # print(s) print(s.name) # 调用__getattr__ # In '__getattr__ # hello del s.name # 调用__delattr__ print(s("name")) # 调用__call__ # None