#python #visual-studio-code #static-methods
#python #visual-studio-code #статические методы
Вопрос:
Я создал класс со staticmethod:
class DetfileDetector(Detector):
def __init__(self, file_path, **kwargs):
super().__init__(**kwargs)
self.detections = self.parse_detfile(file_path)
@staticmethod
def parse_detfile(file_path):
#do somthing with file_path
Когда я вызываю parse_defile
без создания экземпляра класса, я получаю ожидаемый результат
DetfileDetector.parse_detfile('foo.txt')
Однако, когда я вызываю его из функции init(), я получаю сообщение об ошибке:
Ошибка типа: parse_detfile() принимает 1 позиционный аргумент, но было задано 2
Я предполагаю, что смысл в том, что ‘self’ также передается в staticmethod, но это staticmethod, поэтому я ожидал, что self не будет передан.
Мои попытки исправить заключались в том, чтобы установить ‘file_path’ в качестве необязательного аргумента с None по умолчанию, но я получил TypeEroor из
Ошибка типа: parse_detfile() получил несколько значений для аргумента ‘file_path’
Я буду признателен, если кто-нибудь подскажет мне, как правильно его написать.
Редактировать: спасибо за ваши ответы, добавив дополнительную информацию:
- Теперь я вижу, что он терпит неудачу, когда я запускаю его из «интерактивной оболочки python» VSCode (версия 1.50.0-insider), но проходит при запуске из командной строки или без интерактивной оболочки. Я сообщу об этой проблеме разработчикам VSCode.
- Я использую python 3.7.7
Edit2: содержимое Detector
класса
class Detector:
def __init__(self, **kwargs):
self.every = kwargs.pop('every', 1)
self.min_confidence = kwargs.pop('min_confidence', .8)
self.min_wh = kwargs.pop('min_wh', 5)
self.min_ar = kwargs.pop('min_ar', .1)
self.sensor_noise_cov = np.square(np.diag(kwargs.pop('sensor_noise', [10, 10, 1, 10])))
self.classes = object_classes(kwargs.pop('cars_only', True))
Комментарии:
1. Я не могу воспроизвести вашу ошибку. Это работает, как показано в моем ответе ниже.
2. Можете ли вы поделиться содержимым
Detector
class ?3. @PraysonW. Дэниел, я отредактировал вопрос с помощью
Detector
Ответ №1:
Ваш код на самом деле правильный.
Я протестировал его с помощью Python 3.8 и не увидел никаких проблем.
Вы можете вызвать staticmethod, используя класс или экземпляр этого класса.
Смотрите здесь: https://docs.python.org/3/library/functions.html#staticmethod
Он работал так даже в более старых версиях Python, я проверил весь путь до Python 2.7. Так что остается загадкой, почему вы получаете эту ошибку.
Может быть, дать больше контекста для вашего кода?
Комментарии:
1. Это тоже было мое предложение. Проблема не в коде, который представлен здесь
2. @PraysonW. Дэниел, мы на одной странице. Мне любопытно, откуда берется проблема.
3. Мне тоже интересно. Возможно, что-то в
Detector
?4. Спасибо, Прайсон В. Дэниел и Хокли за ваши ответы, я отредактировал вопрос с дополнительной информацией
Ответ №2:
Я думаю, что проблема не в коде, который вы показали. Протестировано на Python 3.6, это работает:
class Detector:
pass
class DetfileDetector(Detector):
def __init__(self, file_path, **kwargs):
super().__init__(**kwargs)
self.detections = self.parse_detfile(file_path)
@staticmethod
def parse_detfile(file_path):
#do somthing with file_path
print(file_path)
DetfileDetector('get.txt')
# get.txt
DetfileDetector.parse_detfile('tex.txt')
# tex.txt
В VSCode добавьте точки останова в свой код в init и parse_detfile и запустите свой код в режиме отладки, чтобы увидеть переменные.
Поэтому проверьте Detector
и посмотрите, есть ли проблема.
Ответ №3:
Измените свой код на это, и он должен работать
class DetfileDetector(Detector):
def __init__(self, file_path, **kwargs):
super().__init__(**kwargs)
self.detections = DetfileDetector.parse_detfile(file_path)
@staticmethod
def parse_detfile(file_path):
#do somthing with file_path
Комментарии:
1. Было бы лучше использовать
self.detections = self.parse_detfile(file_path)
, потому что это не требует жесткого кодирования имени класса в коде (и его не нужно было бы изменять, если имя содержащего класса когда-либо изменится).
Ответ №4:
Я предполагаю, что смысл в том, что ‘self’ также передается в staticmethod, но это staticmethod, поэтому я ожидал, что self не будет передан.
Правильно.
Половина смысла a staticmethod
заключается в том, что вам не нужен экземпляр. Однако он по-прежнему является атрибутом класса, а не функцией верхнего уровня, поэтому:
Я буду признателен, если кто-нибудь подскажет мне, как правильно его написать.
вам нужно искать его внутри класса, таким образом:
def __init__(self, file_path, **kwargs):
super().__init__(**kwargs)
self.detections = DetfileDetector.parse_detfile(file_path)
Да, возможно, это немного неудобно. Но другая половина смысла staticmethod
заключается в том, что вы на самом деле связываете метод с классом таким образом. Если это не кажется преимуществом, вы могли бы вместо этого рассмотреть возможность создания простой функции верхнего уровня вне класса.
Ответ №5:
У меня была такая же проблема. В моем случае это было вызвано тем, что я создал два модуля, в которых был класс с одинаковым именем, и информация об ошибке заставила меня думать, что ошибка была в одном из файлов, хотя на самом деле она была в другом файле. Смотрите Минимальный рабочий пример ниже.
Как вы можете видеть ниже, проблема вызвана тем, что я вызываю file1.Foo
и предоставляю параметр, хотя его конструктор не принимает ни одного параметра. Я был сбит с толку, потому что упоминается ошибка Foo.__init__()
, поэтому я подумал, что это относится к Foo
классу in file1.py
или к тому, в file2.py
котором он находится.
file1.py
class Foo():
def __init__(self):
print('Hello from file1.py')
file2.py
import file1
class Foo():
def __init__(self, text):
pass
def f1(text):
return 'Hello from f1 - ' text
def f2(self):
bar = file1.Foo(Foo.f1('a'))
a = Foo()
a.f2()
Результаты выполнения
python file2.py
Traceback (most recent call last):
File "/home/myusername/e/file2.py", line 15, in <module>
a.f2()
File "/home/myusername/e/file2.py", line 12, in f2
bar = file1.Foo(Foo.f1('a'))
TypeError: Foo.__init__() takes 1 positional argument but 2 were given
Как и следовало ожидать, проблема была просто решена путем добавления параметра в конструктор file1.py
.
file1.py
class Foo():
def __init__(self, text):
print(f'Hello from file1.py')
file2.py
import file1
class Foo():
def __init__(self):
pass
def f1(text):
return 'Hello from f1 - ' text
def f2(self):
bar = file1.Foo(Foo.f1('a'))
a = Foo()
a.f2()
Результаты выполнения
python file2.py
Hello from file1.py
Если у вас такая же проблема, я бы рекомендовал вам взглянуть на те классы, которые имеют то же имя, что и тот, который указан в ошибке.