Могу ли я указать экземпляр-метод другого класса в качестве переменной для моего метода? - PullRequest
2 голосов
/ 27 апреля 2011

Я все еще относительно новичок в Python, 1-2 года в одиночном обучении, и я пытаюсь улучшить свою структуру кода, поэтому я реорганизую некоторые старые программы, которые я написал.В одной программе я определил пару методов для записи файлов.Первый использует «write» для сброса огромного http-ответа.Второй использует «линии писем» для выгрузки различных производных списков, например списков ссылок или форм или других извлеченных данных.

Первоначально я учел название файла:

    @property
    def baseFilename(self):
        unacceptable = re.compile(r'\W+')
        fname = re.sub(unacceptable,'-',self.myUrl)
        t = datetime.datetime.now()
        dstring = "%s%s%s%s%s%s" % (t.year, t.month, t.day, t.hour, t.minute, t.second)
        fullname = fname + '_' + dstring + '.html'
        return fullname

Но у меня большой избыточный блок кода в каждом методе записи:

    def writeFile(self, someHtml, writeMethod=write, prefix="RESPONSE_"):
        '''The calling functions will supply only the data to be written and 
           static prefixes, e.g. "full_" for the entire http-response.
        '''

       fullpath = self.myDump + prefix + self.baseFilename
       with open(fullpath, 'w') as h:
           h.write(someHtml)
           h.close()
       print "saved %s" % fullpath
       return fullpath

    def writeList(self, someList, prefix="mechList_"):
        '''Like write file but for one of the many lists outputted.  
           How do I refactor this, since redundant?
        '''

        fullpath = self.myDump + prefix + self.baseFilename
        with open(fullpath, 'w') as h:
            h.writelines(someList)
            h.close()
        print "saved %s" % fullpath
        return fullpath

Я хотел бы иметь возможность добавить переменную для каждой функции, которая определяет метод записи для использования, например (writeMethod = writelines).Я подумал о том, чтобы просто передать строку и использовать одну из функций черной магии - наверное, exec () - но это не может быть правдой, поскольку никто, кажется, никогда не использует эти функции.Весь этот пример может быть довольно глупым, так как я мог бы просто обойти его, но я решил, что мне было бы полезно знать, как передавать эти виды методов экземпляра (это правильный термин?).Это связано с привязкой и отменой?Все, что мне нужно для хорошего ответа, - это синтаксис, необходимый для передачи 'write', 'writelines' и т. Д. Может быть простым, например: writeMethod = insert_your_syntax_here.Хотелось бы дополнительное объяснение или руководство, хотя.Спасибо.

Ответы [ 2 ]

2 голосов
/ 27 апреля 2011

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

f = obj.method
f(args)
# is equivalent to
obj.method(args)

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

Другой вариант - декоратор для выделения всех общих частей и вывода остальных в обратный вызов, декорированная функция:

def uses_file(prefix_default):
    def decorator(f):
        @functools.wraps(f)
        def decorated(self, data, prefix=prefix_default):
            fullpath = obj.myDump + prefix + obj.baseFilename
            with open(fullpath, 'w') as h:
                f(h, data, prefix)
            print "saved", % fullpath
            return fullpath
        return decorated
    return decorator

# ...

@uses_file(default_prefix="RESPONE_")
def writeFile(self, someHtml, prefix):
   '''...'''
   h.write(someHtml)

@uses_file(default_prefix="mechList_")
def writeList(self, someList, prefix):
    '''...'''
    h.writelines(someList)
1 голос
/ 27 апреля 2011

Есть разные способы сделать это, например, используя лямбды:

def writeFile(self, someHtml, writeMethod=lambda f, data: f.write(data), 
              prefix="RESPONSE_"):
    '''The calling functions will supply only the data to be written and 
       static prefixes, e.g. "full_" for the entire http-response.
    '''

   fullpath = self.myDump + prefix + self.baseFilename
   with open(fullpath, 'w') as h:
       writeMethod(h, someHtml)
       h.close()
   print "saved %s" % fullpath
   return fullpath
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...