Pylint警告`W0212`访问受保护成员:如何避免?

2 投票
1 回答
5948 浏览
提问于 2025-04-18 13:54

Pylint会对访问对象的受保护成员发出警告。它知道当访问来自对象本身时不需要警告,但对于通过对象的属性进行访问时,它就不知道该怎么处理了。

举个例子:

class C(object):

    def __init__(self):
        C.__a = 0

    a = property(lambda self: self.__a)

Pylint会提示“W0212 (protected-access): 访问了客户端类的受保护成员 __a

我不想全局禁用 W0212,而且我也不想每次定义这样的属性时都要重复地局部禁用它 (*)。

有没有什么已知的方法可以解决这个问题?

(*) 就像这样:

class C(object):

    def __init__(self):
        C.__a = 0

    a = property(lambda self: self.__a)  # pylint: disable=W0212

附注

有趣的是,我选择的答案还带来了一个额外的好处,适用于当前版本的Pylint(未来版本可能会有所变化,我无法确定):它保留了Pylint检查不存在成员的能力,正如这个测试所示:

class C1(object):

    member = 0


class C2(object):

    def __init__(self):
        self.__a = C1()

    def a(self):
        return self.__a

    @property
    def b(self):
        return self.__a

    c = property(lambda self: self.__a)


def test_member():

    o = C2()

    print(o.a().member)
    print(o.b.member)
    print(o.c.member)


def test_nonexistent():

    o = C2()

    print(o.a().nonexistent)
    print(o.b.nonexistent)
    print(o.c.nonexistent)

你会收到 print(o.a().nonexistent)print(o.b.nonexistent) 的警告,但不会收到 print(o.c.nonexistent) 的警告。

1 个回答

6

我觉得你可以用一个装饰器,这样代码检查工具可能就不会抱怨了:

class C(object):

    def __init__(self):
        self.__a = 0

    @property
    def a(self):
        return self.__a

    # You can use the decorator to create setters too...
    @a.setter
    def a(self, value):
        self.__a = value

因为这样代码检查工具就能轻松识别a是这个类里的一个方法。否则,你就只能用你列出的那些选项了。你可以选择全局或局部禁用警告,或者根本不禁用——据我所知,没有办法只在特定的情况下禁用警告。

撰写回答