Как вызвать метод класса python?
Метод класса можно вызвать как функцию, указав его название через точку после названия класса:
class MyClass: def my_method(a, b): return a + b MyClass.my_method # MyClass.my_method(3, 5) # 8
Метод объекта/экземпляра класса в Python
Методы — это функции, вызываемые с использованием точечной нотации. Если обратится к методу (функции, определенной в пространстве имен класса) через экземпляр, то получим специальный объект: объект привязанного метода (также называемого методом экземпляра). При вызове он добавляет аргумент self в список аргументов.
Обычно метод вызывается сразу после его привязки:
class MyClass: """Простой пример класса""" i = 12345 def f(self): return 'hello world' x = MyClass() x.f() # 'hello world'
В примере с классом MyClass метод экземпляра класса x.f() возвращает строку «hello world». Нет необходимости вызывать метод сразу, x.f — это объект метода класса и его можно сохранить и вызвать позже. В примере ниже — бесконечный цикл, который будет продолжать печатать «hello world».
xf = x.f while True: print(xf())
Что именно происходит при вызове метода? Заметили, что x.f() был вызван без аргумента? Хотя в определение функции f() был указан один аргумент self . Python всегда вызывает исключение, когда функция, требующая аргумента, вызывается без него, даже если аргумент фактически не используется…
Особенность методов заключается в том, что объект экземпляра передается в качестве первого аргумента self функции. В примере вызов x.f() в точности эквивалентен вызову MyClass.f(x) . В общем случае вызов метода со списком из n аргументов эквивалентен вызову соответствующей функции со списком аргументов, который создается путем вставки объекта экземпляра метода перед первым аргументом.
При ссылке на атрибут экземпляра, не являющийся атрибутом данных, выполняется поиск экземпляра класса. Если имя обозначает допустимый атрибут класса, который является объектом функции, объект метода создается путем упаковки указателей объекта экземпляра и объекта функции, только что найденных вместе в абстрактном объекте: это объект метода. Когда объект метода вызывается со списком аргументов, новый список аргументов создается из экземпляра класса и списка аргументов этого класса, а объект функции вызывается с этим новым списком аргументов.
Первый аргумент метода называется self . Это не более чем соглашение: имя self не имеет абсолютно никакого особого значения для Python. Обратите внимание, что не следуя соглашению, ваш код может быть менее читаемым для других программистов Python и также может быть написана некая программа для просмотра классов, которая будет основываться на этом соглашении.
Любой функциональный объект, являющийся атрибутом класса, определяет метод для экземпляров этого класса. Нет необходимости в том, чтобы определение функции было текстуально заключено в определение класса: присвоение объекта функции локальной переменной в классе также нормально.
# Функция, определенная вне класса def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
Обратите внимание, что эта практика обычно только запутывает читателя программы. Теперь f , g и h — это все атрибуты класса C , которые относятся к функциональным объектам, и, следовательно, все они являются методами экземпляров класса C . Метод h точно эквивалентны g .
Методы могут вызывать другие методы, используя атрибуты метода собственного аргумента:
class Bag: def __init__(self): self.data = [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x)
Методы могут ссылаться на глобальные имена так же, как обычные функции. Глобальной областью видимости, связанной с методом, является модуль, содержащий его определение. Класс никогда не используется в качестве глобальной области видимости. Хотя редко встречаются веские причины для использования глобальных данных в методе, существует много законных вариантов использования глобальной области видимости. Функции и модули, импортированные в глобальную область, могут использоваться методами, а также функциями и классами, определенными в нем. Обычно класс, содержащий метод, сам определяется в этой глобальной области видимости.
Поддержка получения произвольных атрибутов методами.
Связанные методы имеют два специальных атрибута, доступных только для чтения: m.__ self__ — это объект, с которым работает метод, и m.__func__ — это функция, реализующая метод. Вызов m(arg-1, arg-2, . arg-n) полностью эквивалентен вызову m.__func__(m.__self__, arg-1, arg-2, . arg-n) .
Как и объекты функций, связанные объекты методов поддерживают получение произвольных атрибутов. Однако, поскольку атрибуты метода фактически хранятся в базовом объекте функции ( meth.__func__ ), то установка атрибутов метода для связанных методов запрещена. Попытка установить атрибут в методе приводит к возникновению исключения AttributeError . Чтобы установить атрибут метода, необходимо явно установить его для базового объекта функции:
>>> class C: . def method(self): . pass . >>> c = C() >>> c.method.whoami = 'my name is method' # can't set on the method # Traceback (most recent call last): # File "", line 1, in # AttributeError: 'method' object has no attribute 'whoami' >>> c.method.__func__.whoami = 'my name is method' >>> c.method.whoami # 'my name is method'
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Пространство имен и область видимости в классах
- Определение классов
- Объект класса и конструктор класса
- Создание экземпляра класса
- Метод экземпляра класса
- Что такое метод класса и зачем нужен
- Что такое статический метод в классах Python и зачем нужен
- Атрибуты класса и переменные экземпляра класса
- Кэширование методов экземпляра декоратором lru_cache
- Закрытые/приватные методы и переменные класса Python
- Наследование классов
- Множественное наследование классов
- Абстрактные классы
- Перегрузка методов в классе Python
- Что такое миксины и как их использовать
- Класс Python как структура данных, подобная языку C
- Создание пользовательских типов данных
- Специальные (магические) методы класса Python
- Базовая настройка классов Python магическими методами
- Настройка доступа к атрибутам класса Python
- Дескриптор класса для чайников
- Протокол дескриптора класса
- Практический пример дескриптора
- Использование метода .__new__() в классах Python
- Специальный атрибут __slots__ класса Python
- Специальный метод __init_subclass__ класса Python
- Определение метаклассов metaclass
- Эмуляция контейнерных типов в классах Python
- Другие специальные методы класса
- Как Python ищет специальные методы в классах
- Шаблон проектирования Фабрика и его реализация
Как вызвать метод класса без вызова экземпляра?
Подскажите пожалуйста, как возможно вызывать методы без вызова экземпляра класса?
Сейчас у меня реализована функция get_items_list() , она является @classmethod, но мне кажется я делаю это не совсем правильно, вызывая экземпляр внутри функции, но по другому переменные при инициализации не получить. Думал вынести их в атрибуты, но насколько это правильно делать?
На выходе хотелось бы иметь класс для работы с API(OzonRequester) методами, каждый метод (относящийся к запросу определённого API метода) которого можно будет вызывать без инициализации OzonRequester в других классах или модулях.
class OzonRequester(requests.Session): """Doc.""" __API_KEY = os.getenv('MP_Api_Key_Ozon') __CLINET_ID = os.getenv('MP_Client_Id_Ozon') __slots__ = ['__token', '__client_id'] def __init__(self) -> None: """Doc.""" super().__init__() self.base_url = ozon_base_url self.__token = self.__API_KEY self.__client_id = self.__CLINET_ID self.headers.update(< "Host": "api-seller.ozon.ru", "Content-Type": "application/json", "Client-Id": self.__client_id, "Api-Key": self.__token>) @classmethod def get_items_list(cls): """Doc.""" from config import ozon_items_list session = cls() headers = session.headers req_body = response = session.post(urljoin(session.base_url, ozon_items_list), headers=headers, json=req_body)
- Вопрос задан 16 июл. 2023
- 371 просмотр
2 комментария
Простой 2 комментария

Сергей delphinpro @delphinpro
Послушайте, в правилах, пункт 3.1, не просто так написано, что не следует ставить много тегов к вопросам.
Я не подписан на питон, и не хочу его видеть в своей ленте. Но из-за тега ООП вопрос ваш мне попался.
А зачем здесь нужен тег ООП, если речь идет конкретно о том, как это сделать в питоне?

Rett-oo @Rett-oo Автор вопроса
Сергей delphinpro, Здравствуйте, насколько я знаю, Python не является подмножеством ООП, поэтому я указал python, как язык моего примера, и ответ на котором мне будет предпочтительнее. Но если мне ответили бы с примером на другом языке, я бы это так же смог понять. ООП же я использовал именно потому, что в данном вопросе я пытался создать класс с наследованием от другого класса, методы которого использовали методы родительского класса и мне нужно было узнать как правильно использовать classmethod
Решения вопроса 1

Data Analyst
Обычно методы класса используются для объявления альтернативных конструкторов класса, так называемые factory methods. То есть класс метод обычно возвращает cls(*args, **kwargs) Вызывается просто MyClass.classmeth(*args, **kwargs)
Вот например в pandas (у тебя был вопрос, значит используешь библиотеку) есть класс DataFrame. Ты можешь создать экземпляр класса DataFrame(data) А можешь использовать методы класса для альтернативного метода создания экземпляра (из другой структруры) DataFrame.from_dict(some_dict) так вот from_dict это метод класса.
Метод класса он оперирует на уровне класса и не имеет доступа к экземпляру класса. Есть еще статические методы, это по сути python функция которая «связана с классом» но не имеет доступа не экземпляру не к классу.
В чем у тебя здесь смысл попытки использовать методы класса лично мне не понятно. Потому что обычно вызвав метод класса мы инициализируем экземпляр с динамически измененным (данным методом) состоянием класса. Например мы можем поменять значение атрибута класса. Вот тебе на скорую руку бесполезный пример.
class MyClass: currency = 'Dollar' def __init__(self, amaunt): self.amaunt = amaunt def __str__(self): return f'MyClass()' @classmethod def euro(cls, amount): cls.currency = 'Euro' return cls(amount) dollar = MyClass(100) print(dollar) euro = MyClass.euro(100) print(euro)
Если снова вызовешь print(dollar), то он тебе выведет euro. Потому что атрибут класса общий для всех экземпляров оказался измененным.
Как вызвать метод из родительского класса python?
Для вызова метода из родительского класса в Python есть два способа:
- Явное обращение к методу предка
- Функция super()
class Counter: def __init__(self): self.value = 0 def inc(self): self.value += 1 def dec(self): self.value -= 1 # Создаем класс-потомок, при вызове inc увеличивающих значение дважды # Вариант 1 - с прямым обращением к предку: class DoubleCounter(Counter): def inc(self): Counter.inc(self) # явно обращаемся к методу класса предка Counter.inc(self) # и передаем ссылку на экземпляр # Вариант 2 - с применением функции super(): class DoubleCounter(Counter): def inc(self): super().inc() super().inc() num = DoubleCounter() num.value # 0 num.inc() # В обоих случаях, наследованный метод inc() будет работать одинаково num.value # 2
Функция super() названа в честь названия класса-предка: «superclass». Потому что благодаря ей мы получаем ссылку на атрибут предка и заменяем обращение self , создавая таким образом связанный с текущим классом метод, который будет полноценной «оригинальной версией» из класса-предка. При чем если предок сменится, то super в описании класса учтет изменения, и мы получим доступ к поведению нового предка.