Мне было интересно, можно ли избежать некоторых недостатков использования глобальных переменных (см., Например, http://wiki.c2.com/?GlobalVariablesAreBad ), используя пространство имен класса, а не пространство имен global / module для передачи значений переменных. , Следующий код указывает на то, что эти два метода практически идентичны. Как поясняется ниже, использование пространств имен классов дает небольшое преимущество.
Следующие фрагменты кода также показывают, что атрибуты или переменные можно динамически создавать и удалять как в глобальных пространствах имен / модулей, так и в пространствах имен классов.
wall.py
# Note no definition of global variables
class router:
""" Empty class """
Я называю этот модуль «стеной», поскольку он используется для отражения переменных. Он будет действовать как пространство для временного определения глобальных переменных и общеклассовых атрибутов пустого класса «router».
source.py
import wall
def sourcefn():
msg = 'Hello world!'
wall.msg = msg
wall.router.msg = msg
Этот модуль импортирует стену и определяет одну функцию, sourcefn
которая определяет сообщение и передает его с помощью двух разных механизмов, одного через глобальные переменные, а другого через функцию маршрутизатора. Обратите внимание, что переменные wall.msg
и wall.router.message
определены здесь впервые в своих соответствующих пространствах имен.
dest.py
import wall
def destfn():
if hasattr(wall, 'msg'):
print 'global: ' + wall.msg
del wall.msg
else:
print 'global: ' + 'no message'
if hasattr(wall.router, 'msg'):
print 'router: ' + wall.router.msg
del wall.router.msg
else:
print 'router: ' + 'no message'
Этот модуль определяет функцию, destfn
которая использует два разных механизма для получения сообщений, отправленных источником. Это допускает возможность того, что переменная msg может не существовать. destfn
также удаляет переменные после того, как они были отображены.
main.py
import source, dest
source.sourcefn()
dest.destfn() # variables deleted after this call
dest.destfn()
Этот модуль последовательно вызывает ранее определенные функции. После первого вызова dest.destfn
переменных wall.msg
и wall.router.msg
больше не существует.
Вывод программы:
global: Привет, мир!
маршрутизатор: Привет, мир!
global: нет сообщений,
маршрутизатор: нет сообщений
Приведенные выше фрагменты кода показывают, что механизмы переменных модуль / глобальный и класс / класс по существу идентичны.
Если необходимо совместное использование большого количества переменных, загрязнением пространства имен можно управлять либо с помощью нескольких модулей настенного типа, например, wall1, wall2 и т. Д., Либо путем определения нескольких классов типа маршрутизатора в одном файле. Последний вариант немного аккуратнее, поэтому, возможно, представляет собой незначительное преимущество для использования механизма переменных классов.