Python的魔术方法总结

Posted caoshitong

tags:

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

魔术方法:再不需要程序员定义,本身就存在类中的方法就是魔术方法。

魔术方法通常都长这样:__名字__。

1.__str__和__repr__

为了方便记忆看如下列子

技术分享图片
class Course:
    def __init__(self,name,period,price,teacher):
        self.name= name
        self.period = period
        self.price = price
        self.teacher = teacher

    def __str__(self):
        return str : %s %s %s %s % (self.name, self.period, self.price, self.teacher)

    def __repr__(self):
        return repr : %s %s %s %s % (self.name, self.period, self.price, self.teacher)
course_lst = []
python = Course(python,6 month,29800,boss jin)
course_lst.append(python)
linux = Course(linux,5 month,25800,oldboy)
course_lst.append(linux)
for id,course in enumerate(course_lst,1):
    # print(‘%s %s %s %s %s‘%(id,course.name,course.period,course.price,course.teacher))
    print(id,course)
    print(%s %s%(id,course))
    print(str(course))
    print(repr(course))
    print(%r%course)
__str__,__repr__

__str__触发条件:

1.当你打印一个对象的时候触发

2.当你使用%格式化的时候触发

3.str强转数据类型的时候触发

__repr__:

1.__repr__是__str__的备胎

2.有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__

3.repr(obj)内置函数对应的结果是__repr__的返回值

4.当你使用%r的格式化的时候 触发__repr__

2.__new__

在init之前,实例化对象的第一步是__new__创建了一个空间

class Foo:
    def __init__(self):  # 初始化方法
        print(执行了init)

    def __new__(cls, *args, **kwargs):  # 构造方法
        # object.__new__(cls)
        print(执行了new)
        return object.__new__(cls)


obj = Foo()

创造一个对象比喻成捏小人

new是把小人捏出来

init给小人穿衣服

应用:创建单例模式

技术分享图片
class Foo:
    __instance = None

    def __init__(self, name, age):  # 初始化方法
        self.name = name
        self.age = age
        self.lst = [name]

    def __new__(cls, *args, **kwargs):  # 构造方法
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance


obj1 = Foo(alex, 20)
obj2 = Foo(egon, 22)
abc1 = Foo(cao, 33)
print(obj1.lst, obj2.lst, abc1.lst)
单列模式

 3.__del__

对象的__del__是对象在被gc消除回收的时候起作用的一个方法,它的执行一般也就意味着对象不能够继续引用。

看如下列子:

技术分享图片
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.file = open(file, mode=w)

    def write(self):
        self.file.write(sjahgkldhgl)

    def __del__(self):  # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
        # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
        self.file.close()
        print(执行del了)


f = Foo(alex, 20)
print(f)
__del__

4.__len__

如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。

要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))
print(a.__dict__)

菲波那切数列

技术分享图片
# 菲波那切数列
# class Fib(object):
#     def __init__(self, num):
#         a, b, L = 0, 1, []
#         for n in range(num):
#             L.append(a)
#             a, b = b, a + b
#         self.numbers = L
#
#     def __str__(self):
#         return str(self.numbers)
#
#     # __repr__ = __str__
#
#     def __len__(self):
#         return len(self.numbers)
#
#
# f = Fib(10)
# print(f)
# print(len(f))
菲波那切数列

5.__eq__

__eq__ 当判断两个对象的值是否相等时,触发此方法.

class Staff:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
    def __eq__(self, other):
        return self.__dict__ == other.__dict__
alex = Staff(alex,不详)
alex2 = Staff(alex,不详)
alex22 = Staff(alex2,female)
print(alex == alex2)  # alex.__eq__(alex2)
print(alex2 == alex22)

6.__call__

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

class Foo:

    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):

        print(__call__)


obj = Foo() # 执行 __init__
obj()       # 执行 __call__

7.__hash__

# 当一个对象的类中有"__hash__"这个方法时, 那么这个对象就可以执哈希计算

# 前提是要哈希的值是可哈希的. 哈希的不是对象, 而是可以通过对象直接执行"hash(obj)"

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

8.item系列

__getitem__,__setitem,__delitem__

技术分享图片
class Foo:
    def __init__(self,name):
        self.name=name

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

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print(del obj[key]时,我执行)
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print(del obj.key时,我执行)
        self.__dict__.pop(item)

f1=Foo(sb)
f1[age]=18
f1[age1]=19
del f1.age1
del f1[age]
f1[name]=alex
print(f1.__dict__)
item系列

 

 

 

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

PHP中的常见魔术方法功能作用及用法实例

python魔术方法

Python 魔术方法笔记

PHP魔术方法和魔术变量总结

python常用代码片段总结

Python:不应该使用的魔术方法