“翻译(自我)”是如何工作的?

2024-04-25 01:32:41 发布

您现在位置:Python中文网/ 问答频道 /正文

class Keeper(object):

    def __init__(self, keep):
        self.keep = sets.Set(map(ord, keep))

    def __getitem__(self, n):
        if n not in self.keep:
            return None
        return unichr(n)

    def __call__(self, s):
        return unicode(s).translate(self)

makefilter = Keeper

if __name__ == '__main__':
    just_vowels = makefilter('aeiouy')

    print just_vowels(u'four score and seven years ago')   

它会发出“哇哇”的声音。你知道吗

我知道“translate”函数应该接收由创建的表参数字符串.maketrans(). 你知道吗

但是为什么在translate函数中传递“self”。你知道吗

它如何调用getitem函数?你知道吗


Tags: 函数selfreturnifobjectinitdefkeeper
1条回答
网友
1楼 · 发布于 2024-04-25 01:32:41

在我们讨论您的代码片段之前,让我解释一下__getitem__何时为invoke:

这就是__getitem__所说的:

调用__getitem__: object.__getitem__(self, key)来实现对self[key]的评估。你知道吗

对于序列类型,接受的键应该是整数和切片对象。请注意,负索引的特殊解释(如果类希望模拟序列类型)取决于__getitem__()方法。如果键的类型不合适,可能会引发TypeError;如果是序列索引集之外的值(在对负值进行任何特殊解释之后),则应引发IndexError。对于映射类型,如果缺少键(不在容器中),则应引发KeyError。你知道吗

所以,让我们看看下面的片段:

class Keeper(object):
    def __init__(self, keep):
        self.keep = set(map(ord, keep))

if __name__ == '__main__':
    just_vowels = Keeper('aeiouy')
    print just_vowels[1]

输出:由于没有定义__getitem__方法,所以说does not support indexing时出错。你知道吗

Traceback (most recent call last):
  File "tran.py", line 15, in <module>
   print just_vowels[1]
TypeError: 'Keeper' object does not support indexing

现在让我们更改代码段并添加__getitem__以允许对象索引:

class Keeper(object):
    def __init__(self, keep):
        self.keep = set(map(ord, keep))

    def __getitem__(self, n):
        if n in self.keep:
            return unichr(n)
        else:
            return 'Not Found in %s' % self.keep

if __name__ == '__main__':
    just_vowels = Keeper('aeiouy')
    for i in range(97,103):
        print just_vowels[i]

输出:

a
Not Found in set([97, 101, 105, 111, 117, 121])
Not Found in set([97, 101, 105, 111, 117, 121])
Not Found in set([97, 101, 105, 111, 117, 121])
e
Not Found in set([97, 101, 105, 111, 117, 121])

所以,当我们使用self作为映射表(即dictionary)时,最后让我们来看一下您的代码片段。默认情况下,它将调用__getitem__方法来允许索引以及哪些数字在[97, 101, 105, 111, 117, 121]范围内。因此,如果数字或ord值不在集合中,它只返回None,这意味着从unicode字符串中删除。你知道吗

以下是一些支持数字索引的内置python对象:

>>> '__getitem__' in dir(dict)
True
>>> '__getitem__' in dir(list)
True
>>> '__getitem__' in dir(set)
False
>>> '__getitem__' in dir(tuple)
True
>>> '__getitem__' in dir(string)
False
>>>

集合索引示例:

>>> s
set([1, 2])
>>> s[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing
>>>

让我解释一下unicode翻译部分,我希望你已经知道了,但有些人不知道

这就是unicode.translate所说的:

>>> help(unicode.translate)
Help on method_descriptor:

translate(...)
    S.translate(table) -> unicode
    Return a copy of the string S, where all characters have been mapped
    through the given translation table, which must be a mapping of
    Unicode ordinals to Unicode ordinals, Unicode strings or None.
    Unmapped characters are left untouched. Characters mapped to None
    are deleted.
>>

需要table的可以是字典,即Unicode序数到Unicode序数、Unicode字符串或无的映射。

举个例子:从unicode字符串中删除标点:

>>> uni_string = unicode('String with PUnctu@tion!."##')
>>> uni_string
u'String with PUnctu@tion!."##'
>>>

创建标点到无的映射字典:

>>> punc = '!"#$.'
>>> punc_map = {ord(x):None for x in punc }
>>> punc_map
{33: None, 34: None, 35: None, 36: None, 46: None}
>>>

使用此punc_map翻译unicode字符串以删除标点符号:

>>> uni_string
u'String with PUnctu@tion!."##'
>>> uni_string.translate(punc_map)
u'String with PUnctu@tion'
>>>

相关问题 更多 >