Я подумал, можно ли избежать некоторых недостатков использования глобальных переменных (см., Например, http://wiki.c2.com/?GlobalVariablesAreBad), используя пространство имен класса вместо глобального / модульного пространства имен для передачи значений переменных. Следующий код указывает на то, что эти два метода по существу идентичны. Существует небольшое преимущество в использовании пространств имен классов, как описано ниже.
Следующие фрагменты кода также показывают, что атрибуты или переменные могут динамически создаваться и удаляться как в глобальных пространствах имен / пространствах модулей, так и в пространствах имен классов.
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: Привет, мир!
маршрутизатор: Привет, мир!
глобальный: нет сообщения
маршрутизатор: нет сообщения
Приведенные выше фрагменты кода показывают, что механизмы module / global и class / class variable по существу идентичны.
Если необходимо совместно использовать большое количество переменных, загрязнение пространства имен можно контролировать с помощью нескольких модулей типа стены, например, wall1, wall2 и т. д. или путем определения нескольких классов маршрутизатора в одном файле. Последнее немного опрятнее, поэтому, возможно, представляет собой незначительное преимущество для использования механизма переменной класса.