Питонический способ доступа к атрибуту класса внутри класса - PullRequest
0 голосов
/ 28 мая 2018

Мне было интересно, как вы думаете, как получить доступ к атрибуту класса из функции внутри класса.Я не нашел ссылки на PEP8 или популярного вопроса по этому поводу.например,

class MyClass(object):
    BAR = 1
    def foo(self):
        # Way A:
        print(self.BAR)

        # Way B:
        print(MyClass.BAR)

Доступ через «Я» кажется разумным, поскольку атрибут принадлежит одному и тому же классу, близкая ссылка для очевидной ссылки того же класса.С другой стороны, доступ через само имя класса является понятным, поскольку он является статическим и делает происхождение использования понятным, а также может быть более понятным, поскольку он связан с классом ' name .

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Для чтения не имеет значения, какой вы используете - self.BAR и MyClass.BAR синтаксически эквивалентны, если у вас нет иерархии классов, где подкласс переопределяет значение BAR.

Для записиОни не то же самое.Запись в self.BAR эффективно создаст новую переменную, которая является локальной для экземпляра объекта self, поэтому любые чтения из self.BAR из другого экземпляра объекта не увидят изменений.Это может быть довольно ужасно для отладки, потому что из кода не очевидно, что должно произойти, потому что он чувствителен к синхронизации.определенный уровень в иерархии классов, или type(self).BAR или self.__class__.BAR, если вы хотите что-то, что безопасно для наследования.Это определенно и очевидно переменная класса, позволяющая избежать проблемы, описанной выше, с динамическими псевдонимами, возникающими во время выполнения.Использование self просто печет в некоторой хрупкости, что может быть трудно обнаружить в будущем.

0 голосов
/ 28 мая 2018

Когда explicity именует имя класса, вы запрещаете подклассу переопределять вашего атрибута.

С другой стороны, использование self дает вам эту гибкость .Рассмотрим следующий код:

class MyClass(object):
    BAR = 1
    def foo(self):
        # Way A:
        print(self.BAR)

        # Way B:
        print(MyClass.BAR)


class SubClass(MyClass):
    BAR = 2

class SubClass2(MyClass):
    pass

# output
>>> a = SubClass()
>>> a.foo()
2
1
>>> b = SubClass2()
>>> b.foo()
1
1
...