Python 魔术方法

Python 魔术方法

Python 魔术方法教程描述了什么是 Python 魔术方法,并说明了如何使用它们。 在本教程中,我们介绍了一些常见的魔术方法。

Python 魔术方法

Python 魔术方法是为我们的自定义类添加功能的特殊方法。 它们被双下划线包围(例如__add __())。

Python 中有许多魔术方法。 它们中的大多数用于非常特殊的情况。 我们将提到一些更流行的方法。

__add__方法

__add__()方法用于实现加法运算。 在 Python 中,数字不是原始文字,而是对象。 num + 4表达式等效于num.__add__(4)。

add_dict.py

#!/usr/bin/env python

class MyDict(dict):

def __add__(self, other):

self.update(other)

return MyDict(self)

a = MyDict({'de': 'Germany'})

b = MyDict({'sk': 'Slovakia'})

print(a + b)

在示例中,我们有一个自定义词典,该词典使用__add__()实现加法运算。

class MyDict(dict):

def __add__(self, other):

self.update(other)

return MyDict(self)

自定义词典继承自内置dict。 __add__()方法与update()方法添加两个字典,并返回新创建的字典。

a = MyDict({'de': 'Germany'})

b = MyDict({'sk': 'Slovakia'})

我们创建两个简单的字典。

print(a + b)

我们添加两个字典。

$ ./add_dict.py

{'de': 'Germany', 'sk': 'Slovakia'}

这是输出。

__init__和__str__方法

__init__()方法用于初始化对象。 此方法用于实现对象的构造函数。 __str__()提供了对象可读的输出。

init_str.py

#!/usr/bin/env python

class Person:

def __init__(self, name, occupation):

self.name = name

self.occupation = occupation

def __str__(self):

return f'{self.name} is a {self.occupation}'

p = Person('John Doe', 'gardener')

print(p)

在示例中,我们有一个 Person 类,具有两个属性:name和occupation。

def __init__(self, name, occupation):

self.name = name

self.occupation = occupation

在__init__()方法中,我们将实例变量设置为传递给构造函数的值。

def __str__(self):

return f'{self.name} is a {self.occupation}'

__str__()方法可以很好地输出对象。

$ ./init_str.py

John Doe is a gardener

这是输出。

__repr__方法

__repr__()方法由内置函数repr()调用。 当它评估返回对象的表达式时,在 Python shell 上使用它。

__str__()用于提供对象的人类可读版本,__repr__()用于提供对象的完整表示。 后者的输出也更适合开发人员。

如果缺少__str__()实现,则将__repr__()方法用作后备。

def __repr__(self):

return '<{0}.{1} object at {2}>'.format(

self.__module__, type(self).__name__, hex(id(self)))

对象的__repr__()方法的默认实现类似于上面的代码。

repr_ex.py

#!/usr/bin/env python

class Person:

def __init__(self, name, occupation):

self.name = name

self.occupation = occupation

def __str__(self):

return f'{self.name} is a {self.occupation}'

def __repr__(self):

return f'Person{{name: {self.name}, occupation: {self.occupation}}}'

p = Person('John Doe', 'gardener')

print(p)

print(repr(p))

该示例实现了__str__()和__repr__()方法。

$ ./repr_ex.py

John Doe is a gardener

Person{name: John Doe, occupation: gardener}

这是输出。

__len__和__getitem__方法

__len__()方法返回容器的长度。 当我们在对象上使用内置的len()方法时,将调用该方法。 __getitem__()方法定义项目访问([])运算符。

french_deck.py

#!/usr/bin/env python

import collections

from random import choice

Card = collections.namedtuple('Card', ['suit', 'rank'])

class FrenchDeck:

ranks = [str(i) for i in range(2, 11)] + list('JQKA')

suits = ["heart", "clubs", "spades", "diamond"]

def __init__(self):

self.total = [Card(suit, rank)

for suit in self.suits for rank in self.ranks]

def __len__(self):

return len(self.total)

def __getitem__(self, index):

return self.total[index]

deck = FrenchDeck()

print(deck[0])

print(len(deck))

print(choice(deck))

该方法用于实现法语卡片组。

Card = collections.namedtuple('Card', ['suit', 'rank'])

我们使用一个命名的元组来定义一个Card类。 namedtuple是用于创建元组类的工厂功能。 每张卡都有一套西装和一个等级。

def __len__(self):

return len(self.total)

__len__()方法返回卡座(52)中的卡数。

def __getitem__(self, index):

return self.total[index]

__getitem__()实现索引操作。

print(deck[0])

我们得到卡组的第一张牌。 这称为__getitem__()。

print(len(deck))

这将调用__len__()方法。

$ ./french_deck.py

Card(suit='heart', rank='2')

52

Card(suit='diamond', rank='A')

这是输出。

__int__和__index__方法

调用__int__()方法以实现内置的int()功能。 当在切片表达式中使用对象以及内置的hex(),oct()和bin()函数时,__index__()方法将类型转换为 int。

char_ex.py

#!/usr/bin/env python

class Char:

def __init__(self, val):

self.val = val

def __int__(self):

return ord(self.val)

def __index__(self):

return ord(self.val)

c1 = Char('a')

print(int(c1))

print(hex(c1))

print(bin(c1))

print(oct(c1))

在示例中,我们创建一个自定义的Char类,该类实现了int(),hex(),bin()和oct()函数。

./char_ex.py

97

0x61

0b1100001

0o141

这是输出。

__eq __,__ lt__和__gt__方法

__eq__()实现了==运算符。 __lt__()实现了<运算符,__gt__()实现了>运算符。

pouch.py

#!/usr/bin/env python

import collections

Coin = collections.namedtuple('coin', ['rank'])

# a gold coin equals to two silver and six bronze coins

class Pouch:

def __init__(self):

self.bag = []

def add(self, coin):

self.bag.append(coin)

def __eq__(self, other):

val1, val2 = self.__evaluate(other)

if val1 == val2:

return True

else:

return False

def __lt__(self, other):

val1, val2 = self.__evaluate(other)

if val1 < val2:

return True

else:

return False

def __gt__(self, other):

val1, val2 = self.__evaluate(other)

if val1 > val2:

return True

else:

return False

def __str__(self):

return str(self.bag)

def __evaluate(self, other):

val1 = 0

val2 = 0

for coin in self.bag:

if coin.rank == 'g':

val1 += 6

if coin.rank == 's':

val1 += 3

if coin.rank == 'b':

val1 += 1

for coin in other.bag:

if coin.rank == 'g':

val2 += 6

if coin.rank == 's':

val2 += 3

if coin.rank == 'b':

val2 += 1

return val1, val2

pouch1 = Pouch()

pouch1.add(Coin('g'))

pouch1.add(Coin('g'))

pouch1.add(Coin('s'))

pouch2 = Pouch()

pouch2.add(Coin('g'))

pouch2.add(Coin('s'))

pouch2.add(Coin('s'))

pouch2.add(Coin('b'))

pouch2.add(Coin('b'))

pouch2.add(Coin('b'))

print(pouch1)

print(pouch2)

if pouch1 == pouch2:

print('Pouches have equal value')

elif pouch1 > pouch2:

print('Pouch 1 is more valueable than Pouch 2')

else:

print('Pouch 2 is more valueable than Pouch 1')

我们有一个可以容纳金,银和青铜硬币的小袋。 一枚金币等于两个银币和六个铜币。 在示例中,我们使用 Python magic 方法为 pouch 对象实现了三个比较运算符。

def __eq__(self, other):

val1, val2 = self.__evaluate(other)

if val1 == val2:

return True

else:

return False

在__eq__()方法中,我们首先评估两个小袋的值。 然后我们比较它们并返回布尔结果。

def __evaluate(self, other):

val1 = 0

val2 = 0

for coin in self.bag:

if coin.rank == 'g':

val1 += 6

if coin.rank == 's':

val1 += 3

if coin.rank == 'b':

val1 += 1

for coin in other.bag:

if coin.rank == 'g':

val2 += 6

if coin.rank == 's':

val2 += 3

if coin.rank == 'b':

val2 += 1

return val1, val2

__evaluate()方法计算两个袋的值。 它穿过小袋的硬币,并根据硬币的等级增加一个值。

pouch1 = Pouch()

pouch1.add(Coin('g'))

pouch1.add(Coin('g'))

pouch1.add(Coin('s'))

我们创建第一个袋,并在其中添加三个硬币。

if pouch1 == pouch2:

print('Pouches have equal value')

elif pouch1 > pouch2:

print('Pouch 1 is more valueable than Pouch 2')

else:

print('Pouch 2 is more valueable than Pouch 1')

我们将小袋与比较运算符进行比较。

2D 向量示例

在下面的示例中,我们介绍了几种其他魔术方法,包括__sub__(),__mul__()和__abs__()。

vector.py

#!/usr/bin/env python

import math

class Vec2D:

def __init__(self, x, y):

self.x = x

self.y = y

def __add__(self, other):

return Vec2D(self.x + other.x, self.y + other.y)

def __sub__(self, other):

return Vec2D(self.x - other.x, self.y - other.y)

def __mul__(self, other):

return self.x * other.x + self.y * other.y

def __abs__(self):

return math.sqrt(self.x ** 2 + self.y ** 2)

def __eq__(self, other):

return self.x == other.x and self.y == other.y

def __str__(self):

return f'({self.x}, {self.y})'

def __ne__(self, other):

return not self.__eq__(other)

u = Vec2D(0, 1)

v = Vec2D(2, 3)

w = Vec2D(-1, 1)

a = u + v

print(a)

print(a == w)

a = u - v

print(a)

a = u * v

print(a)

print(abs(u))

print(u == v)

print(u != v)

在示例中,我们有一个Vec2D类。 我们可以比较,加,减和乘向量。 我们还可以计算向量的长度。

$ ./vector.py

(2, 4)

False

(-2, -2)

3

1.0

False

True

这是输出。

在本教程中,我们使用了 Python 魔术方法。

您可能也对以下相关教程感兴趣: Python 字符串, Python Jinja 教程和 Python 教程。

相关星际资讯

双卡双待和双卡多模是什么意思
365bet吧

双卡双待和双卡多模是什么意思

🕒 07-01 👁️ 1204
中科睿芯公司介绍北京中科睿芯科技集团有限公司成立于2014年11月,由中国科学院计算技术研究所及其高通量中心核心团队(S...
经常做同一个梦的原因
365体育投注官网

经常做同一个梦的原因

🕒 07-05 👁️ 5245