静态函数变量的Pythonic方式(小范围,单个初始化)?

时间:2017-10-24 10:30:37

标签: python python-3.x static

def clean_word(word):
    chars_to_clean = {',', ':', '.','/'} #static?
    res = ''
    for c in word:
        if c not in chars_to_clean:
            res += c
    return res

在C ++中,我会将chars_to_clean声明为static,这样我一方面可以最小化其范围,另一方面可以避免重复分配。我怎样才能在Python中实现这些目标?

我可以将chars_to_clean作为类变量,但我希望尽可能缩小范围。
我可以将它作为函数的属性,但我怀疑在每次调用时都会重复赋值。

2 个答案:

答案 0 :(得分:2)

您没有

你发布它时代码很好(范围很小,创建这么小的一组并没有花足够的时间来打扰它。

但是,如果您想更改代码,请参阅以下建议:

将其设为默认参数

如果您希望{strong>避免重复创建 chars_to_clean集,您可以执行以下操作(请参阅"Least Astonishment" and the Mutable Default Argument):

def clean_word(word, chars_to_clean = {',', ':', '.','/'})
    res = ''
    for c in word:
        if c not in chars_to_clean:
            res += c
    return res

这样设置只被设置一次(当python读取函数定义时),你可以重用该函数来清理不同的字符。这是危险,如果你改变了集合(意外),你不管怎么做。

将其设为大写

如果您想明确(按照惯例)此变量是常量,请将变量名称更改为全部大写,并且不要担心范围

将其设为字符串

您可以在python中执行"a" in "abcde"。通过将其从集合更改为字符串,您可以将其设置为不可变。 (但仍然可以重新分配)

使其成为没有setter的类属性

如果您想避免意外重新分配/修改,请将其设为没有setter的类属性。然而,这个解决方案可能是一种过度杀伤。

class A:
    @property
    def chars_to_clean(self):
        return ",:./"

在这种情况下,您仍然可以执行A.chars_to_clean = "abc",但A().chars_to_clean="asd"A().chars_to_clean[0]=w会引发错误,第一个错误是由于缺少setter,第二个是由于字符串的不变性。

答案 1 :(得分:1)

函数是一个对象,因此您可以在对象上设置属性并使用它们。它们不是“私密的”,但在阅读代码时,您可以看到它们密切相关。

类似的东西:

def clean_word(word):
    res = ''
    for c in word:
        if c not in clean_word.chars_to_clean:
            res += c
    return res

clean_word.chars_to_clean = {',', ':', '.','/'} 

这不是很优雅,因为你必须在定义函数后定义 chars_to_clean

在定义函数时定义属性但检查 hasattr 的另一个选项也不是很好:

def clean_word(word):
    if not hasattr(clean_word, 'chars_to_clean'):
        clean_word.chars_to_clean = {',', ':', '.','/'}     
    res = ''
    for c in word:
        if c not in clean_word.chars_to_clean:
            res += c
    return res