вызов функции из класса в python-по-другому
EDIT2: спасибо всем за помощь! EDIT: при добавлении @staticmethod он работает. Однако мне все еще интересно, почему я получаю ошибку типа здесь.
Я только что начал OOPS и совершенно новичок в этом. У меня есть очень простой вопрос относительно различных способов вызова функции из класса. У меня есть testClass.py файл с кодом:
Я вызываю этот класс из другого файла под названием main.py со следующим код:
это работает без каких-либо проблем. Тем не менее, я хотел использовать класс намного проще.
теперь я поместил следующий код в testClass.py файл. На этот раз я отбросил функцию init.
вызов этого использования;
это не работает. Может ли кто-нибудь объяснить, что происходит неправильно в случае 2? Как мне использовать этот класс?
ошибка, которую я получаю: «TypeError: testAddition() занимает ровно 2 аргумента (3 дан)»
5 ответов
вы должны использовать self в качестве первого параметра метода
во втором случае вы должны использовать
и в вашем коде вы можете сделать следующее
если вы используете класс без создания экземпляра переменной first
это дает вам ошибку «TypeError: unbound method»
если вы хотите сделать это, вам понадобится @ staticmethod decorator
затем в вашем коде вы можете использовать
отказ от ответственности: это не просто ответ на вопрос, это больше похоже на совет, даже если ответ можно найти на ссылках
IMHO: объектно-ориентированное программирование на Python сосет довольно много.
метод диспетчеризации не очень прост, вам нужно знать о связанном / несвязанном экземпляре / классе (и статическом!) методы; вы можете иметь множественное наследование и иметь дело с устаревшими и новыми классами стилей (ваш был старым стилем) и знать, как работает MRO, свойства.
вкратце: слишком сложно, с большим количеством вещей, происходящих под капотом. Позвольте мне сказать даже, это unpythonic, как есть много различных способов для достижения той же вещи.
мой совет: используйте ООП только тогда, когда это действительно полезно. Обычно это означает написание классов, которые реализуют хорошо известные протоколы и легко интегрируются с остальной частью системы. Не создавайте много классов только ради написания объектно-ориентированных код.
возьмите хорошее чтение на эту страницу:
вы найдете их весьма полезными.
Если вы действительно хотите узнать ООП, я бы предложил начать с более обычного языка, такого как Java. Это не так весело, как Python, но это более предсказуемо.
Метод объекта/экземпляра класса в Python.
Методы — это функции, вызываемые с использованием точечной нотации. Если обратится к методу (функции, определенной в пространстве имен класса) через экземпляр, то получим специальный объект: объект привязанного метода (также называемого методом экземпляра). При вызове он добавляет аргумент self в список аргументов.
Обычно метод вызывается сразу после его привязки:
В примере с классом MyClass метод экземпляра класса x.f() возвращает строку "hello world". Нет необходимости вызывать метод сразу, x.f — это объект метода класса и его можно сохранить и вызвать позже. В примере ниже — бесконечный цикл, который будет продолжать печатать "hello world".
Что именно происходит при вызове метода? Заметили, что x.f() был вызван без аргумента? Хотя в определение функции f() был указан один аргумент self . Python всегда вызывает исключение, когда функция, требующая аргумента, вызывается без него, даже если аргумент фактически не используется…
Особенность методов заключается в том, что объект экземпляра передается в качестве первого аргумента self функции. В примере вызов x.f() в точности эквивалентен вызову MyClass.f(x) . В общем случае вызов метода со списком из n аргументов эквивалентен вызову соответствующей функции со списком аргументов, который создается путем вставки объекта экземпляра метода перед первым аргументом.
При ссылке на атрибут экземпляра, не являющийся атрибутом данных, выполняется поиск экземпляра класса. Если имя обозначает допустимый атрибут класса, который является объектом функции, объект метода создается путем упаковки указателей объекта экземпляра и объекта функции, только что найденных вместе в абстрактном объекте: это объект метода. Когда объект метода вызывается со списком аргументов, новый список аргументов создается из экземпляра класса и списка аргументов этого класса, а объект функции вызывается с этим новым списком аргументов.
Первый аргумент метода называется self . Это не более чем соглашение: имя self не имеет абсолютно никакого особого значения для Python. Обратите внимание, что не следуя соглашению, ваш код может быть менее читаемым для других программистов Python и также может быть написана некая программа для просмотра классов, которая будет основываться на этом соглашении.
Любой функциональный объект, являющийся атрибутом класса, определяет метод для экземпляров этого класса. Нет необходимости в том, чтобы определение функции было текстуально заключено в определение класса: присвоение объекта функции локальной переменной в классе также нормально.
Обратите внимание, что эта практика обычно только запутывает читателя программы. Теперь f , g и h — это все атрибуты класса C , которые относятся к функциональным объектам, и, следовательно, все они являются методами экземпляров класса C . Метод h точно эквивалентны g .
Методы могут вызывать другие методы, используя атрибуты метода собственного аргумента:
Методы могут ссылаться на глобальные имена так же, как обычные функции. Глобальной областью видимости, связанной с методом, является модуль, содержащий его определение. Класс никогда не используется в качестве глобальной области видимости. Хотя редко встречаются веские причины для использования глобальных данных в методе, существует много законных вариантов использования глобальной области видимости. Функции и модули, импортированные в глобальную область, могут использоваться методами, а также функциями и классами, определенными в нем. Обычно класс, содержащий метод, сам определяется в этой глобальной области видимости.
Поддержка получения произвольных атрибутов методами.
Связанные методы имеют два специальных атрибута, доступных только для чтения: m.__ self__ — это объект, с которым работает метод, и m.__func__ — это функция, реализующая метод. Вызов m(arg-1, arg-2, . arg-n) полностью эквивалентен вызову m.__func__(m.__self__, arg-1, arg-2, . arg-n) .
Как и объекты функций, связанные объекты методов поддерживают получение произвольных атрибутов. Однако, поскольку атрибуты метода фактически хранятся в базовом объекте функции ( meth.__func__ ), то установка атрибутов метода для связанных методов запрещена. Попытка установить атрибут в методе приводит к возникновению исключения AttributeError . Чтобы установить атрибут метода, необходимо явно установить его для базового объекта функции:
Как из функции одного класса запустить функцию другого
Теперь по существу: чтобы вызвать «функцию класса», которая по-хорошему называется методом, необходимо создать объект этого класса. Объясняется это тем, что класс – модель некоего объекта, а методы моделируют его поведение. Представьте класс «Собака». Чтобы услышать лай, нам нужна хотя бы одна собака. Вы же в своём примере пытаетесь услышать лай не от самой собаки а от абстрактного понятия о том, что такое вообще собака. Если проще, в ООП, чтобы что-то происходило, нужен тот, кто будет это делать, то есть, объект класса.
Если предыдущее было запутано и непонятно, вот пример проще. Классы и типы данных – во многом синонимы. Вы ведь не можете возвести в степень, например, тип int .
Да, в этом примере оператор не работает немного по другой причине (Python распознаёт его как переменную и не находит объявления), но тем не менее смысл должен быть ясен.
Вы можете возвести число типа int в степень, но сам тип – нет.
Для программиста на C++ можно было бы привести гораздо более наглядные примеры, но я не уверен, что автор вопроса знает этот язык.