Python类的内置方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python类的内置方法相关的知识,希望对你有一定的参考价值。

本章介绍一下python类中的一些内置方法。内置的方法有很多,有些内置方法在object类中已经定义,子类可以拿来直接使用,也可以重写,但是有些内置方法object类中没有,比如 __len__ 方法(len()方法会调用 对应类中的 __len__ 方法),需要根据需求来进行定义~

__str__和__repr__

对象的字符串显示 会调用__str__ 或 __repr__ 方法,__str__ 和 __repr__ 方法在object中已经定义,默认都是输出对象在内存中的地址,有时候根据需求需要重写这两个方法~

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

    def __repr__(self):
        return ‘(%s,%s)‘ % (self.name, self.city)

    def __str__(self):
        return ‘(%s,%s)‘ % (self.name, self.age)

p = Person(‘Kitty‘, 19, ‘HZ‘)
print(p)         # (Kitty,19),调用 __str__
print(str(p))   # (Kitty,19),调用 __str__
print(repr(p)) # (Kitty,HZ),调用 __repr__

print(‘%s‘ % p)   # (Kitty,19),调用 __str__
print(‘%r‘ % p)   # (Kitty,HZ),调用 __repr__

在交互式解释其中,直接输出对象,会调用 __repr__ 方法

>>> p = Person(‘Kitty‘, 19, ‘HZ‘)
>>> p
(Kitty,HZ)

Tip:

  • str函数,print函数,%s 会调用 __str__ 方法;
  • repr函数,交互式解释器,%r 会调用 __repr__ 方法;
  • 若是 仅重写了__repr__ 方法,那么 str函数,print函数,%s 就会用__repr__ 方法来代替,但是反过来 __str__ 方法 不会代替 __repr__ 方法~

__format__

用于将对象格式化输出

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

    def __format__(self, format_spec):
        fmt = {
            ‘-‘: ‘{obj.name}-{obj.age}-{obj.city}‘,
            ‘/‘: ‘{obj.name}/{obj.age}/{obj.city}‘
        }[format_spec]
        return fmt.format(obj = self)

p = Person(‘Kitty‘, 19, ‘HZ‘)

# format 函数会调用对象的绑定方法 __format__
print(format(p, ‘-‘))  
print(format(p, ‘/‘))

# 输出结果:
Kitty-19-HZ
Kitty/19/HZ

__del__

析构方法,当对象在内存中被释放时,会自动触发执行。但是此方法一般无须定义,因为Python解释器会来完成内存的分配和释放工作,所以,析构方法的调用是由解释器在进行垃圾回收时自动触发执行的。

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

    def __del__(self):
        print(‘delete...‘)

p = Person(‘Kitty‘, 19, ‘HZ‘)
del p

# 输出结果:
delete...

item系列

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

    def __getitem__(self, item):
        return self.__dict__[item]

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

    def __delitem__(self, item):
        self.__dict__.pop(item)

    def __delattr__(self, key):
        self.__dict__.pop(key)

p = Person(‘Kitty‘, 19)
print(p[‘name‘])    # Kitty,调用 __getitem__ 方法

p[‘age‘] = 18
print(p[‘age‘])       # 18

p[‘city‘] = ‘HZ‘       
print(p.__dict__)   # 调用 __setitem__ 方法
# {‘name‘: ‘Kitty‘, ‘age‘: 18, ‘city‘: ‘HZ‘}

del p[‘city‘]             # 调用 __delitem__ 方法
print(p.__dict__) 
# {‘name‘: ‘Kitty‘, ‘age‘: 18}

del p.age               # 调用 __delattr__ 方法
print(p.__dict__)
# {‘name‘: ‘Kitty‘}

__len__

len(obj) 会调用obj的 __len__ 方法

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

    def __len__(self):
        return len(self.__dict__)

p = Person(‘Kitty‘, 19)
print(len(p))       # 2

__call__

对象后面加括号,就会触发 __call__ 方法的执行,即调用方式:对象() 或者 类()()

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def __call__(self):
        print(‘hello‘ + ‘ ‘ + self.__name)

p = Person(‘Kitty‘, 19)()     # hello Kitty
# p()

__new__

在类的是实例化过程中,第一个被调用的是 __new__方法。在对象的初始化之前首先要创建对象,__new__方法正是用来创建这个对象~
?;
类的实例化过程也可以通过如下语句来实现:

>>> p = object.__new__(Person) 
>>> Person.__init__(p, ‘Kitty‘, 18)
>>> p.name
‘Kitty‘

在Person类中重写 __new__方法:

class Person:
    country = "China"
    def __new__(cls, name, age):
        print(‘__new__ called‘)
        return super(Person, cls).__new__(cls)

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

    def speak(self, word):
        print(word)

p = Person(‘Kitty‘, 18)          # 实例化对象
print(‘name : %s‘ % p.name)

# 输出结果:
__new__ called
name : Kitty

可以看到 __new__ 方法 是先于 __init__ 方法被调用的~
类的实例化过程大致步骤如下:
1、p = Person(‘Kitty‘, 18) ,会调用 Person类的 __new__ 方法,并传递 name 和 age 参数
2、__new__ 方法 会创建一个 Person类的对象并返回
3、最后利用这个对象调用类的 __init__ 方法 完成初始化,__init__ 方法的第一个参数是self,对象在调用 __init__ 方法时会将自己当做参数传递给 这个self。

单例模式

重写 __new__ 来实现单例模式~

class Person:
   def __new__(cls, *args, **kwargs):
       if not hasattr(cls, ‘_instance‘):
           cls._instance = super(Person, cls).__new__(cls, *args, **kwargs)
       return cls._instance

p1 = Person()
p2 = Person()

print(p1)    # <__main__.Person object at 0x108eb6438>
print(p2)    # <__main__.Person object at 0x108eb6438>

对象的内存地址相同,则表示为同一个对象~

__hash__和__eq__

在判断两个对象是否一致时,往往会用到这两个函数~

__hash__

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def __hash__(self):
        return hash(str(self.__name))

p = Person(‘Kitty‘, ‘19‘)
print(hash(p))

__eq__

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

    def __eq__(self, obj):
        if self.name == obj.name and self.age == obj.age:
            return True

p1 = Person(‘Kitty‘, ‘19‘)
p2 = Person(‘Kitty‘, ‘19‘)
print(p1 == p2)     # True

以上是关于Python类的内置方法的主要内容,如果未能解决你的问题,请参考以下文章

Python中类的属性方法及内置方法

Python类的内置方法

Python中,类的特殊方法与内置函数的关联

Python的内置方法和类的继承举例

python内置方法

python——类的内置方法