您的位置:

8. Python 魔术或邓德方法

Python 魔术或邓德方法

更新:

Python 中的魔法方法是以双下划线开始和结束的特殊方法。它们也被称为邓德方法。魔法方法并不意味着由您直接调用,而是在某个动作上从类内部进行调用。例如,当您使用+运算符将两个数字相加时,在内部将调用__add__()方法。

Python 中的内置类定义了许多神奇的方法。使用dir()函数查看一个类继承的魔法方法数量。 例如,下面列出了在int类中定义的所有属性和方法。

>>> dir(int)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

正如您在上面看到的,int 类包含了各种由双下划线包围的神奇方法。例如,__add__方法是一种神奇的方法,当我们使用+运算符将两个数字相加时,它就会被调用。 考虑以下示例。 T3】

>>> num=10
>>> num + 5
15
>>> num.__add__(5)
15

可以看到,当你做num+10时,+运算符调用__add__(10)方法。 也可以直接打num.__add__(5)会给出同样的结果。 然而,如前所述,魔法方法并不意味着被直接调用,而是在内部,通过一些其他的方法或动作。

在 Python 中,魔术方法最常用于定义预定义运算符的重载行为。例如,默认情况下,算术运算符对数字操作数进行运算。这意味着数值对象必须与+、-、*、/等运算符一起使用。+运算符也被定义为字符串、列表和元组类中的串联运算符。我们可以说+运算符是重载的。

为了使重载行为在您自己的自定义类中可用,应该重写相应的 magic 方法。例如,为了将+运算符用于用户定义类的对象,它应该包括__add__()方法。

让我们看看如何实现和使用一些重要的魔术方法。

new()方法

Java 和 C# 等语言使用新的运算符来创建类的新实例。在 Python 中,__new__()魔法方法在__init__()方法之前被隐式调用。__new__()方法返回一个新的对象,然后由__init__()初始化。

Example: new()

class Employee:
    def __new__(cls):
        print ("__new__ magic method is called")
        inst = object.__new__(cls)
                return inst
    def __init__(self):
        print ("__init__ magic method is called")
        self.name='Satya' 

当您创建Employee类的实例时,上面的示例将产生以下输出。

>>> emp = Employee()
__new__ magic method is called
__init__ magic method is called

因此,在__init__()方法之前调用__new__()方法。

str()方法

另一个有用的魔法方法是__str__()。它被重写以返回任何用户定义类的可打印字符串表示形式。 我们已经看到str()内置函数从对象参数返回一个字符串。例如,str(12)返回‘12’。当被调用时,它调用 int 类中的__str__()方法。

>>> num=12
>>> str(num)
'12'
>>> #This is equivalent to
>>> int.__str__(num)
'12'

现在让我们重写 Employee 类中的__str__()方法,以返回其对象的字符串表示。

Example: str()

class Employee:
    def __init__(self):
        self.name='Swati'
        self.salary=10000
    def __str__(self):
        return 'name='+self.name+' salary=$'+str(self.salary) 

查看str()函数如何在内部调用员工类中定义的__str__()方法。这就是为什么它被称为神奇的方法!

>>> e1=Employee()
>>> print(e1)
name=Swati salary=$10000

add()方法

在下面的示例中,一个名为 distance 的类定义了两个实例属性- ft 和 inch。这两个距离对象的添加需要使用重载+运算符来执行。

为了实现这一点,神奇的方法__add__()被覆盖,它执行两个对象的英尺和英寸属性的添加。 方法返回对象的字符串表示。

Example: Override add()

class distance:
    def __init__(self, x=None,y=None):
        self.ft=x
        self.inch=y
    def __add__(self,x):
        temp=distance()
        temp.ft=self.ft+x.ft
        temp.inch=self.inch+x.inch
        if temp.inch>=12:
            temp.ft+=1
            temp.inch-=12
            return temp
    def __str__(self):
        return 'ft:'+str(self.ft)+' in: '+str(self.inch) 

运行上面的 Python 脚本来验证+运算符的重载操作。

>>> d1=distance(3,10)
>>> d2=distance(4,4)
>>> print("d1= {} d2={}".format(d1, d2))
d1= ft:3 in: 10 d2=ft:4 in: 4
>>> d3=d1+d2
>>> print(d3)
ft:8 in: 2

ge()方法

在距离类中增加以下方法来重载>=运算符。

Example: ge()

class distance:
    def __init__(self, x=None,y=None):
        self.ft=x
        self.inch=y
    def __ge__(self, x):
        val1=self.ft*12+self.inch
        val2=x.ft*12+x.inch
        if val1>=val2:
            return True
        else:
            return False 

当使用>=运算符并返回真或假时,调用该方法。相应地,可以显示适当的信息

>>> d1=distance(2,1)
>>> d2=distance(4,10)
>>> d1>=d2
False

重要的魔术方法

下表列出了 Python 3 中的重要魔术方法。

初始化和构造 描述
新 (cls,其他) 在对象的实例化中被调用。
init(自身,其他) 被 new 方法调用。
del(自我) 析构函数方法。
一元运算符和函数 描述
pos(自我) 被要求一元正,例如+someobject。
neg(自我) 为一元负数被调用,例如-someobject。
abs(自我) 被内置的 abs()函数调用。
_ 反转 _(自) 使用~运算符进行反演。
_ 回合 _(自身,n) 被内置 round()函数调用。
_ 楼层 _(自) 被内置的 math.floor()函数调用。
ceil(自我) 被内置的 math.ceil()函数调用。
trunc(自助) 被内置的 math.trunc()函数调用。
扩充赋值 描述
iadd(自身,其他) 通过赋值来调用加法,例如 a +=b。
isub(自身,其他) 在带赋值的减法运算中被调用,例如 a -=b。
imul(自身、其他) 被要求进行乘法运算,例如 a *=b。
ifloordiv(自身,其他) 通过赋值调用整数除法,例如 a //=b。
idiv(自身,其他) 被叫去分配任务,例如 a /=b。
itruediv(自身,其他) 被叫去真正的部门分配任务
imod(自我,其他) 通过赋值进行模调用,例如 a%=b。
ipow(自身、其他) 在有赋值的指数上被调用,例如 a **=b。
ilshift(自身,其他) 通过赋值(如 a<<=b)在按位左移时被调用。
irshift(自身,其他) 通过赋值进行右位移位调用,例如 a >>=b。
_ _(自身,其他) 通过赋值按位“与”调用,例如 a&=b。
ior(自我,其他) 通过赋值按位“或”调用,例如 a|=b。
ixor(自身、其他) 通过赋值进行按位异或调用,例如^=b.
类型转换魔术方法 描述
int(自我) 由内置 int()方法调用,将类型转换为 int。
float(自) 由内置的浮点()方法调用,将类型转换为浮点。
_ 复杂 _(自我) 由内置的 complex()方法调用,将类型转换为复杂类型。
_ 10 月 _ 日(自我) 由内置的 int oct()方法调用,将类型转换为八进制。
hex(自) 由内置的 int hex()方法调用,将类型转换为十六进制。
_ 索引 _(自我) 当对象在切片表达式中使用时,在类型转换为 int 时被调用。
trunc(自助) 从 math.trunc()方法调用。
弦乐魔术方法 描述
str(自我) 方法调用以返回类型的字符串表示形式。
repr(自我) 由内置的 int repr()方法调用以返回类型的机器可读表示形式。
unicode(自我) 由内置的 unicode()方法调用以返回类型的 unicode 字符串。
format(self,formatstr) 由内置的 string.format()方法调用以返回新的字符串样式。
hash(自我) 由内置哈希()方法调用以返回一个整数。
_ 非零 _(自身) 由内置 bool()方法调用以返回真或假。
dir(自助) 由内置的 dir()方法调用以返回类的属性列表。
sizeof(自我) 由内置的 sys.getsizeof()方法调用以返回对象的大小。
属性魔法方法 描述
getattr(自我,姓名) 当访问不存在的类的属性时调用。
setattr(自身、名称、值) 为类的属性赋值时调用。
delattr(自我,姓名) 在删除类的属性时调用。
运算符魔术方法 描述
_ 添加 _(自身、其他) 使用+运算符在添加操作时被调用
sub(自身、其他) 使用-运算符在减法运算时被调用。
mul(自身、其他) 使用*运算符调用乘法运算。
floordiv(自身、其他) 使用//运算符调用楼层划分操作。
truediv(自我,其他) 使用/运算符调用除法运算。
mod(自身、其他) 使用%运算符进行模运算时调用。
_ _(自身,其他[,模]) 使用**运算符计算功率时被调用。
lt(自我,其他) 使用
le(自我,其他) 使用< =运算符进行比较时调用。
eq(自我,他人) 使用==运算符进行比较时调用。
ne(自身,其他) 使用进行比较时调用!=运算符。
ge(自身,其他) 使用> =运算符进行比较时调用。

因此,您可以使用适当的魔法方法在自定义类中添加各种功能。

Further Reading ** https://rszalski . github . io/magic cmmethod*****