Создание Объектно-ориентированного сценария Python

Когда класс предка также имеет метод с тем же именем, и это не обязательно объявляется виртуальное, Вы видели бы предупреждение компилятора (поскольку Вы скроете этот метод).

, Другими словами: Вы говорите компилятору, что знаете, что Вы скрываете функцию предка и заменяете ее этой новой функцией и делаете так сознательно.

И почему Вы сделали бы это? Если метод является виртуальным в родительском классе, единственная причина состоит в том, чтобы предотвратить полиморфизм. Другой тогда, который просто переопределяет и не называет наследованными. Но если родительский метод не объявляется виртуальный (и Вы не можете изменить это, потому что Вы не владеете кодом, например), можно наследоваться тому классу и позволить людям наследоваться классу, не видя предупреждение компилятора.

22
задан greenie 28 November 2009 в 19:04
поделиться

4 ответа

To speed up your existing code measurably, add def main(): before the assignment to tokenList, indent everything after that 4 spaces, and at the end put the usual idiom

if __name__ == '__main__':
  main()

(The guard is not actually necessary, but it's a good habit to have nevertheless since, for scripts with reusable functions, it makes them importable from other modules).

This has little to do with "object oriented" anything: it's simply faster, in Python, to keep all your substantial code in functions, not as top-level module code.

Second speedup, change cleanedInput into a list, i.e., its first assignment should be = [], and wherever you now have +=, use .append instead. At the end, ''.join(cleanedInput) to get the final resulting string. This makes your code take linear time as a function of input size (O(N) is the normal way of expressing this) while it currently takes quadratic time (O(N squared)).

Then, correctness: the two statements right after continue never execute. Do you need them or not? Remove them (and the continue) if not needed, remove the continue if those two statements are actually needed. And the tests starting with if diff will fail dramatically unless the previous if was executed, because diff would be undefined then. Does your code as posted perhaps have indentation errors, i.e., is the indentation of what you posted different from that of your actual code?

Considering these important needed enhancements, and the fact that it's hard to see what advantage you are pursuing in making this tiny code OO (and/or modular), I suggest clarifying the indenting / correctness situation, applying the enhancements I've proposed, and leaving it at that;-).

Edit: as the OP has now applied most of my suggestions, let me follow up with one reasonable way to hive off most functionality to a class in a separate module. In a new file, for example foobar.py, in the same directory as the original script (or in site-packages, or elsewhere on sys.path), place this code:

def token_of(line):
  return line.partition(':')[-1].strip()

class FileParser(object):
  def __init__(self, filename):
    self.tokenList = open(filename, 'r')

  def cleaned_input(self):
    cleanedInput = []
    prevLine = 0

    for line in self.tokenList:
        if line.startswith('LINE:'):
            lineNo = int(token_of(line))
            diff = lineNo - prevLine - 1
            cleanedInput.append('\n' * (diff if diff>1 else diff+1))
            prevLine = lineNo
        else:
            cleanedLine = token_of(line)
            cleanedInput.append(cleanedLine + ' ')

    return cleanedInput

Your main script then becomes just:

import sys
import foobar

def main():
    thefile = foobar.FileParser(sys.argv[1])
    print thefile.cleaned_input()

if __name__ == '__main__':
  main()
50
ответ дан 29 November 2019 в 04:12
поделиться

When I do this particular refactoring, I usually start with an initial transformation within the first file. Step 1: move the functionality into a method in a new class. Step 2: add магический вызов, приведенный ниже, чтобы снова запустить файл как сценарий:

class LineCleaner:

    def cleanFile(filename):
        cleanInput = ""
        prevLine = 0
        for line in open(filename,'r'):         
           <... as in original script ..>

if __name__ == '__main__':
     cleaner = LineCleaner()
     cleaner.cleanFile(sys.argv[1]) 
1
ответ дан 29 November 2019 в 04:12
поделиться

Вы можете обойтись без создания функции и размещения в ней всей своей логики. Однако для полной «объектной ориентированности» вы можете сделать что-то вроде этого:

ps - ваш опубликованный код содержит ошибку в строке continue - он всегда выполняется, и последние 2 строки никогда не будут выполняться.

class Cleaner:
  def __init__(...):
    ...init logic...
  def Clean(self):
    for line in open(self.tokenList):
      ...cleaning logic...
    return cleanedInput

def main(argv):
  cleaner = Cleaner(argv[1])
  print cleaner.Clean()
  return 0

if '__main__' == __name__:
  sys.exit(main(sys.argv))
0
ответ дан 29 November 2019 в 04:12
поделиться

Если представленный код - это весь код Только не добавляйте никаких классов !!

Ваш код слишком прост для этого !! Подход ООП добавил бы ненужную сложность.

Но если все еще не будет. Put all code into function eg.

def parse_tokenized_input(file):
    tokenList = open(file, 'r')
    cleanedInput = ''
    prevLine = 0
    #rest of code

at end add:

if __name__ == '__main__':
    parse_tokenized_input(sys.argv[1])

If code works correct put def of function to new file (and all needed imports!) eg. mymodyle.py

your script now will be:

from mymodule.py import parse_tokenized_input

if __name__ == '__main__':
        parse_tokenized_input(sys.argv[1])

Oh and think out better name for your function and module (module should have general name).

0
ответ дан 29 November 2019 в 04:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: