自定义类-例子

  • 2018-09-14
  • 461
  • 0
# 多行输出结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

自定义类的使用例子

1. 例子一:

class Money(object):

    currency_rates = {
        '$': 1,
        '€': 0.88,
    }

    def __init__(self, symbol, amount):
        self.symbol = symbol
        self.amount = amount

    def __repr__(self):
        return '%s%.2f' % (self.symbol, self.amount)

    def convert(self, other):
        ''' Convert other amount to our currency '''
        new_amount = (
            other.amount / self.currency_rates[other.symbol] \
            * self.currency_rates[self.symbol]
        )

        return Money(self.symbol, new_amount)


soda_cost = Money('$', 5.25)
soda_cost
pizza_cost = Money('€', 7.99)
pizza_cost
$5.25
€7.99

该类定义为给定的货币符号和汇率定义了一个货币汇率,指定了一个初始化器(也称为构造函数),并实现 __repr__,因此当我们打印这个类时,我们会看到一个友好的表示,例如 $2.00 ,这是一个带有货币符号和金额的 Money('$', 2.00) 实例。最重要的是,它定义了一种方法,允许你使用不同的汇率在不同的货币之间进行转换。
我们可以使用魔术方法使得这个类的实例之间可以相互交互。假设我们希望能够将这个类的两个实例一起加在一起,即使它们是不同的货币。为了实现这一点,我们可以在 Money 类上实现 __add__ 这个魔术方法:

class Money(object):

    currency_rates = {
        '$': 1,
        '€': 0.88,
    }

    def __init__(self, symbol, amount):
        self.symbol = symbol
        self.amount = amount

    def __repr__(self):
        return '%s%.2f' % (self.symbol, self.amount)

    def convert(self, other):
        ''' Convert other amount to our currency '''
        new_amount = (
            other.amount / self.currency_rates[other.symbol] \
            * self.currency_rates[self.symbol]
        )

        return Money(self.symbol, new_amount)

    def __add__(self, other):
        ''' Add 2 Money instances using "+" '''
        new_amount = self.amount + self.convert(other).amount
        return Money(self.symbol, new_amount)


soda_cost = Money('$', 5.25)
pizza_cost = Money('€', 7.99)
soda_cost + pizza_cost
pizza_cost + soda_cost
$14.33
€12.61

2. 例子二: 魔术方法映射到内置函数,

例如__len__()映射到len().

class Alphabet(object):
    letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

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


my_alphabet = Alphabet()
len(my_alphabet)
26

3. 例子三: 自定义迭代器

迭代我们自己的自定义类?首先,让我们来澄清一些术语。

  • 要成为一个可迭代对象,一个类需要实现 __iter__()
  • __iter__() 方法需要返回一个迭代器
  • 要成为一个迭代器,一个类需要实现 __next__()(或在 Python 2中是 next()),当没有更多的项要迭代时,必须抛出一个 StopIteration 异常。

使用场景:
我们有一个 Server 实例在不同的端口上运行不同的服务,如 http 和 ssh。其中一些服务处于 active 状态,而其他服务则处于 inactive 状态。

class Server(object):
    services = [
        {'active': False, 'protocol': 'ftp', 'port': 21},
        {'active': True, 'protocol': 'ssh', 'port': 22},
        {'active': True, 'protocol': 'http', 'port': 21},
    ]
    def __iter__(self):
        for service in self.services:
            if service['active']:
                yield service['protocol'], service['port']


for protocol, port in Server():
    print('service %s is running on port %d' % (protocol, port))
service ssh is running on port 22
service http is running on port 21

yield 关键字到底是什么?在定义生成器函数时使用 yield。这有点像 return,虽然 return 在返回值后退出函数,但 yield 会暂停执行直到下次调用它。这允许你的生成器的功能在它恢复之前保持状态。


版权声明: 本网站所有资源采用BY-NC-SA 4.0协议进行授权,转载应当以相同方式注明文章来自:自定义类-例子 - 一方的天地

评论

还没有任何评论,你来说两句吧

发表评论

陕ICP备18010914号
知识共享许可协议
本作品由一方天地采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资源请尽快联系站长,本站会在24h内删除有争议的资源。 -