Python特殊方法

__str__和__repr__方法

使用print打印操作会首先尝试__str__和str内置函数,它通常应该返回一个友好的提示
当__str__不存在的时候,会去找__repr__是否定义,定义则打印__repr__中定义的内容

class Person(object):
    def __init__(self,name,gender):
        self.name = name
        self.gender =gender
    def __str__(self):
        return '(Person:%s,%s)'%(self.name,self.gender)
p = Person('Bob','male')
print (p) # (Person:Bob,male)
#但是当我们输入p的时候我们并不能显示出字符串
p #<__main__.Person object at 0x035FC950>
因为 Python 定义了__str__()__repr__()两种方法,__str__()用于显示给用户,而__repr__()用于显示给开发人员。
有一个偷懒的定义__repr__的方法:
class Person(object):
    def __init__(self,name,gender):
        self.name = name
        self.gender =gender
    def __str__(self):
        return '(Person:%s,%s)'%(self.name,self.gender)
    __repr__ = __str__
p = Person('Bob','Male')
p  #(Person:Bob,Male)

__cmp__:
class Student(object):
    def __init__(self,name,score):
        self.name = name
        self.score = score
    def __str__(self):
        return '(%s:%s)' % (self.name,self.score)
    __repr__ = __str__
    def __lt__(self,s):
        return self.name < s.name
    def __gt__(self,s):
        return self.name > s.name
    def eg(self,s):
        return self.name == s.name
L = [Student('Tim',99),Student('Bob',88),Student('Alice',77)]
print (sorted(L))  # [(Alice:77), (Bob:88), (Tim:99)]

__len__函数
class Student(object):
    def __init__(self,*args):
        self.names = args
    def __len__(self):
        return len(self.names) 
L = Student('Bob','Alice','Tim')
print (len(L))  # 3
 

__slots__

如果要限制添加的属性,例如,Student类只允许添加 name、genderscore 这3个属性,就可以利用Python的一个特殊的__slots__来实现。

__slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。

 
class Student(object):
    __slots__ = ('name','gender','score')
    def __init__(self,name,gender,score):
        self.name = name
        self.gender = gender
        self.score = score
s = Student('Bob','male',59)
s.name = 'Tim'
s.score = 99
s.grade = 'A'
 

__call__:

一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()

class Person(object):
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender
    def __call__(self,friend):
        print ('My name is %s...' % self.name)
        print ('My name is %s...'% friend)
p = Person('Bob','male')
p ('Tim')

item系列

__getitem__(self, item)            对象通过 object[key] 触发
__setitem__(self, key, value)    对象通过 object[key] = value 触发
__delitem__(self, key)            对象通过 del object[key] 触发
class Func:
    def __getitem__(self, item):
        # object[item] 触发
        return self.__dict__[item]

    def __setitem__(self, key, value):
        # object[key] = value 触发
        self.__dict__[key] = value

    def __delitem__(self, key):
        # del object[key] 触发
        print('delitem: 删除key')
        del self.__dict__[key]

    def __delattr__(self, item):
        # del object.item 触发
        print('delattr: 删除key')
        del self.__dict__[item]
f = Func()
f['name'] = 'hkey'  # __setitem__
f['age'] = 20   # __setitem__
print(f.name)   # 对象属性原本的调用方式
print(f['name'])    # __getitem__
del f['name']   # __delitem__
print('------')
del f.age   # __delattr__

__new__

class Foo:
  def __init__(self, *args, **kwargs):
    print('in init function.')    
  def __new__(cls, *args, **kwargs):    # 实例化时,首先执行__new__方法
    print('in new function.')
    return object.__new__(cls, *args, **kwargs)
f = Foo()

__hash__调用 hash(object) 触发

class Foo:
    def __init__(self):
        self.a = 1
        self.b = 5
    def __hash__(self):
        return hash(str(self.a) + str(self.b))
f = Foo()
print(hash(f))

__eq__当两个对象进行比较时,触发

class Foo:
    def __init__(self):
        self.a = 1
        self.b = 5

    def __eq__(self, other):
        if self.a == other.a and self.b == other.b:
            return True
        return False
a = Foo()
b = Foo()
print(a == b)   # 执行这个比较的时候,就调用了 __eq__ 方法

猜你喜欢

转载自www.cnblogs.com/larken/p/10545342.html
今日推荐