Как объявить метод, который принимает экземпляр в качестве аргумента в Python?

Я знаю, что это, наверное, глупый вопрос, но я новичок в ООП в Python, и если я объявляю функцию def myFunction( b) и передаю экземпляр объекта, я получаю TypeError: ожидаемая строка или буфер.

Чтобы быть более конкретным, у меня есть следующий код, который я использую для анализа обобщенной молекулярной формулы и исключения из нее объекта.

 class SummaryFormula: def __init__( self, summaryFormula): self.atoms = {} for atom in re.finditer( "([AZ][az]{0,2})(\d*)", summaryFormula): symbol = atom.group(1) count = atom.group(2) def extend( self, b): # these are the two dictionaries of both molecules originalFormula = self.atoms.copy() self.atoms.clear() addAtoms = SummaryFormula( b) # and here both dictionaries are merged for atom in addAtoms.atoms.keys(): if atom in originalFormula.keys(): self.atoms[ atom] = originalFormula[ atom] self.atoms[ atom] += addAtoms.atoms[ atom] else: pass for atom in originalFormula.keys(): if atom not in self.atoms.keys(): self.atoms[ atom] = originalFormula[ atom] #this is what works now test = SummaryFormula( "H2CFe2") test.extend("H5C5") #result is a molecule H7C6Fe2 #this is what I want instead test = SummaryFormula( "H2CFe2") toExtend = SummaryFormula( "H5C5") test.extend( toExtend) 

Спасибо, Томас

Ричард Кук прав. Однако есть еще одна проблема: в extend вы говорите:

 addAtoms = SummaryFormula( b) 

Таким образом, экземпляр SummaryFormula передается в метод __init__ SummaryFormula. Здесь (по модулю re.finditer опечатки) этот объект присваивается re.finditer :

 for atom in re.finditer( "([AZ][az]{0,2})(\d*)", summaryFormula) 

Функция re.finditer ожидает строку; он не знает, что делать с экземпляром SummaryFormula .

Есть несколько способов исправить это. Самое простое – проверить, у вас уже есть экземпляр SummaryFormula, прежде чем пытаться его создать:

 if isinstance(b, SummaryFormula): addAtoms = b else if isinstance(b, str): addAtoms = SummaryFormula(b) else: raise TypeError("Expected a SummaryFormula or equivalent string.") 

Во-первых, программа должна включать модуль re .

Во-вторых, у вас есть опечатка в строке 4:

 for atom in re.finditer( "([AZ][az]{0,2})(\d*)", SummaryFormula): 

должен прочесть

 for atom in re.finditer( "([AZ][az]{0,2})(\d*)", summaryFormula): 

т. е. нижний регистр в summaryFormula .

SummaryFormula относится к названию класса, а summaryFormula относится ко второму параметру (после self ) метода __init__ .

В-третьих, строка addAtoms = SummaryFormula(b) передает экземпляр SummaryFormula качестве аргумента b (назначается в верхней части скрипта test.extend(toExtend) .

Фиксированная программа должна выглядеть так:

 import re class SummaryFormula: def __init__(self, summaryFormula): self.atoms = {} for atom in re.finditer("([AZ][az]{0,2})(\d*)", summaryFormula): symbol = atom.group(1) count = atom.group(2) def extend( self, b): # these are the two dictionaries of both molecules originalFormula = self.atoms.copy() self.atoms.clear() # PASS AN APPROPRIATE VALUE HERE! addAtoms = SummaryFormula("SOME STRING") # and here both dictionaries are merged for atom in addAtoms.atoms.keys(): if atom in originalFormula.keys(): self.atoms[ atom] = originalFormula[ atom] self.atoms[ atom] += addAtoms.atoms[ atom] else: pass for atom in originalFormula.keys(): if atom not in self.atoms.keys(): self.atoms[ atom] = originalFormula[ atom] #this is what works now test = SummaryFormula("H2CFe2") test.extend("H5C5") #result is a molecule H7C6Fe2 #this is what I want instead test = SummaryFormula("H2CFe2") toExtend = SummaryFormula("H5C5") test.extend(toExtend) 

с заменой "SOME STRING" на заданный строковый литерал или ссылку на строковые переменные. Я не знаю точное намерение программы, поэтому я оставлю ее кому-то еще, чтобы определить, что эта программа должна передать конструктору SummaryFormula на этом этапе.

Надеюсь, это поможет!

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

В общем, все в Python является объектом. Это ключевая концепция в Python, поэтому, если вы новичок в этом языке, потратите некоторое время на знакомство, так как это поможет вашему коду писать более кратким и питоническим.

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

 >>> a = 2 >>> open(a, 'r') TypeError: coercing to Unicode: need string or buffer, int found 

Здесь возникает ошибка, так как функция открытия файла open ожидает строку, а не целое число.