类的内置方法

__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
原文地址:https://www.cnblogs.com/liusouthern/p/8330851.html