Статические методы - как вызвать метод из другого метода?

98

Когда у меня есть обычные методы для вызова другого метода в классе, я должен сделать это

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

но когда у меня есть статические методы, я не могу писать

self.dosomethingelse()

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

Изменить: какой беспорядок. Хорошо, я вернул вопрос к исходному вопросу. У меня уже есть ответ на второй вопрос в комментарии Питера Хансена. Если вы думаете, что я должен открыть другой вопрос, чтобы получить ответ, который у меня уже есть, пожалуйста, скажите мне.

Пабло
источник
3
@pablo: суть вопроса не меняешь !! Закончите этот вопрос и начните еще один !!
jldupont, 07
ладно ладно. вы имеете в виду удалить вопрос? Ответ уже есть в комментарии Питера Хансена
Пабло
@pablo: вы не можете удалить здесь, это было бы не вежливо для всех, кто ответил на ваш вопрос. Вам нужно принять ответ и создать новый вопрос.
jldupont, 07
1
@pablo: и просто для ясности: ответ должен быть принят на исходную формулировку вопроса. Не волнуйтесь, здесь вы узнаете свой путь. Ура :-)
jldupont 07

Ответы:

80

class.method должно сработать.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
источник
17
Здесь следует добавить совет: очевидно, что методы классов не имеют недостатков по сравнению со статическими методами, а методы классов позволяют в будущем расширить этот метод для вызова других методов класса. Таким образом, ему всегда следует отдавать предпочтение, даже если в этом нет немедленной необходимости.
u0b34a0f6ae
1
@ u0b34a0f6ae: Я не знаю, делаю я что-то хорошее или нет ... но я определил декоратор внутри класса. Декоратор должен быть «статическим методом», а не «методом класса».
André Caldas
@ u0b34a0f6ae Всегда ли методы классов потокобезопасны? В моем случае использования я использую статические методы в потоках, чтобы предотвратить случайный доступ к классу, который может быть небезопасным для потоков.
aquavitae
@ u0b34a0f6ae всегда немного сильновато . Например, использование статических методов PySpark можно использовать в заданиях rdd, а методы классов - нет.
Laurens Koppenol
141

Как мне сделать в Python вызов статического метода из другого статического метода того же класса?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()
Варвариук
источник
Вызов Test.static_method_to_call()должен работать и из других нестатических и неклассовых методов этого класса, верно? (... и, возможно, другие классы тоже?)
gr4nt3d
Да, Test.static_method_to_call()работать будет откуда угодно.
warvariuc
11

ПРИМЕЧАНИЕ - похоже, вопрос немного изменился. Ответ на вопрос о том, как вы вызываете метод экземпляра из статического метода, заключается в том, что вы не можете не передать экземпляр в качестве аргумента или не создать экземпляр этого экземпляра внутри статического метода.

Далее следует в основном ответ «как вызвать статический метод из другого статического метода»:

Имейте в виду , что есть разница между статическими методами и методами класса в Python. Статический метод не принимает неявный первый аргумент, тогда как метод класса принимает класс в качестве неявного первого аргумента (обычно clsпо соглашению). Имея это в виду, вот как вы это сделаете:

Если это статический метод:

test.dosomethingelse()

Если это метод класса:

cls.dosomethingelse()
Джейсон Бейкер
источник
1
вы можете использовать только cls.dosomethingelse()внутри определения класса.
jldupont 07
3
Чтобы быть более точным, вы можете использовать только cls.dosomethingelse()из самого метода класса. Точно так же, как вы можете использовать только selfиз самого метода экземпляра.
Джейсон Бейкер,
1
извините, я неправильно написал вопрос. Упс !. Я хотел написать «Как мне сделать в Python для вызова метода экземпляра из другого статического метода того же класса», а не «Как мне сделать в Python для вызова статического метода из другого статического метода того же класса». class »
Пабло
@pablo: В этом случае вам нужно написать еще один вопрос и закончить этот.
jldupont, 07
@jldupont, у меня уже есть ответ, но в одном комментарии. Что мне делать, потому что я не могу принять это, но было бы напрасной тратой стереть вопрос, не так ли?
Пабло,
4

ОК, основное различие между методами класса и статическими методами:

  • Метод класса имеет собственную идентичность, поэтому их нужно вызывать из INSTANCE.
  • с другой стороны, статический метод может использоваться несколькими экземплярами, поэтому его нужно вызывать из КЛАССА
Ахмад Дваик
источник
Это кажется неправильным, но смысл здесь расплывчатый без примера, поэтому трудно сказать. В основном, «методы класса» не нужно вызывать «изнутри экземпляра» ... вы можете вызывать MyClass.class_method()из любого места, о котором известно MyClass(может быть, вы думали о «методах экземпляра»?)
млцы
1

Если они не зависят от класса или экземпляра, почему бы просто не сделать их функцией? Поскольку это казалось бы очевидным решением. Если, конечно, вы не думаете, что его нужно будет перезаписать, создать подкласс и т. Д. Если это так, то предыдущие ответы - лучший выбор. Скрестив пальцы, я не получу скидку за то, что просто предлагаю альтернативное решение, которое может или не может соответствовать чьим-то потребностям;).

Поскольку правильный ответ будет зависеть от варианта использования рассматриваемого кода;) Наслаждайтесь

AppHandwerker
источник
0

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

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

надеюсь, что это поможет вам :)

Ахмад Дваик
источник
3
IMO этот подход заметно хуже, чем просто использование @classmethodдля объявления ваших методов и использование cls.dosomethingelse()внутри cls.dosomething()- хуже с точки зрения производительности (создание экземпляров объектов только для получения доступа к статическому методу) и удобочитаемости (это непросто, и я предполагаю, что этот вид шаблона стало шаблонным, вся кодовая база может стать довольно сложной для простого человека для синтаксического анализа)
Кайл Уайлд
Как я читал где-то еще в SO, вместо того, чтобы инициализировать экземпляр напрямую для вызова метода, вы можете просто вызвать его - он инициализируется сам по себе.
Накилон