Должен ли я использовать класс в этом: чтение XML-файла с использованием lxml - PullRequest
1 голос
/ 15 июня 2010

Этот вопрос является продолжением моего предыдущего вопроса, в котором я задал вопрос о обходе ElementTree.

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

Мой вопрос:

Является ли это приемлемой практикой?Я слышал global переменные плохие.Если я не сделаю это global, мне предложили сделать class.Но мне действительно нужно создать class?Какие преимущества я бы получил от такого подхода.Обратите внимание, что я буду обрабатывать только один ElementTree экземпляр за цикл, операции доступны только для чтения.Если я не использую class, как и где мне объявить это ElementTree, чтобы он был доступен по всему миру?(Обратите внимание, что я буду импортировать этот модуль)

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

Ответы [ 3 ]

0 голосов
/ 15 июня 2010

Я, как правило, сожалею об этом, когда поддаюсь искушению дать модуль, например, метод load_file () , который устанавливает глобальный параметр, который другие функции модуля могут затем использовать для поиска файл, о котором они должны были говорить. Например, это значительно усложняет тестирование, и как только мне нужны два XML-файла, возникает проблема. Кроме того, каждая функция должна проверять наличие файла и выдавать ошибку, если его нет.

Если я хочу быть функциональным, я просто хочу, чтобы каждая функция принимала XML-файл в качестве аргумента.

Если я хочу быть объектно-ориентированным, у меня будет класс MyXMLFile , методы которого могут просто смотреть на self.xmlfile или любой другой.

Два подхода более или менее эквивалентны, когда нужно передать только одну вещь, например файл; но когда число вещей в «состоянии» становится больше, чем несколько, я нахожу классы более простыми, потому что я могу прикрепить все эти вещи в классе.

(Я отвечаю на ваш вопрос? Я все еще не совсем понимаю, какой ответ вы хотите.)

0 голосов
/ 15 июня 2010

Есть несколько причин, по которым глобальные переменные плохие . Во-первых, у вас появляется привычка объявлять глобальные переменные, что не является хорошей практикой, хотя в некоторых случаях имеют смысл глобальные переменные - например, PI. Глобалы также создают проблемы, когда вы намеренно или случайно используете имя локально. Или хуже, когда вы думаете , что используете имя локально, но в действительности вы присваиваете новое значение глобальной переменной. Эта конкретная проблема зависит от языка, и python обрабатывает ее по-разному в разных случаях.

class A:
   def __init__(self):
      self.name = 'hi'

x = 3
a = A()

def foo():
   a.name = 'Bedevere'
   x = 9

foo()
print x, a.name #outputs 3 Bedevere

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

class Knights:
   def __init__(self, name='Bedevere'):
       self.name = name
   def knight(self):
       self.name = 'Sir ' + self.name
   def speak(self):
       print self.name + ":", "Run away!"

class FerociousRabbit:
   def __init__(self):
       self.death = "awaits you with sharp pointy teeth!"
   def speak(self):
       print "Squeeeeeeee!"

def cave(thing):
   thing.speak()
   if isinstance(thing, Knights):
       thing.knight()

def scene():
   k = Knights()
   k2 = Knights('Launcelot')
   b = FerociousRabbit()
   for i in (b, k, k2):
      cave(i)

Этот пример иллюстрирует несколько хороших принципов. Во-первых, сила Python при вызове функций - FerociousRabbit и Knights - это два разных класса, но они имеют одинаковую функцию speak (). В других языках, чтобы сделать что-то подобное, им, по крайней мере, нужно было бы иметь один и тот же базовый класс. Причина, по которой вы захотите сделать это, заключается в том, что вы можете написать функцию (пещеру), которая может работать с любым классом, имеющим метод speak (). Вы можете создать любой другой метод и передать его функции пещеры:

class Tim:
   def speak(self):
       print "Death awaits you with sharp pointy teeth!"

Так что в вашем случае, когда вы имеете дело с elementTree, скажите, что когда-нибудь в будущем вам нужно также начать анализировать журнал apache. Хорошо, если вы делаете чисто функциональную программу, вы в основном работаете. Вы можете изменять и расширять свою текущую программу, но если вы хорошо написали свои функции, вы можете просто добавить новый класс в смесь, и (технически) все будет очень увлекательно.

0 голосов
/ 15 июня 2010

Прагматично, ожидается ли рост вашего кода?Несмотря на то, что люди воспринимают ООП как правильный путь, я обнаружил, что иногда лучше взвешивать затраты: выгоды (преимущества) всякий раз, когда вы реорганизуете фрагмент кода.Если вы хотите расширить это, то ООП является лучшим вариантом, так как вы можете расширить и настроить любой будущий вариант использования, сохраняя при этом себя от ненужных затрат времени на обслуживание кода.В противном случае, если он не сломан, не исправляйте его, ИМХО.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...