Определить метод вне определения класса? - PullRequest
38 голосов
/ 26 февраля 2012
class MyClass:
    def myFunc(self):
        pass

Могу ли я создать MyFunc() вне определения класса, может быть, даже в другом модуле?

Ответы [ 4 ]

68 голосов
/ 26 февраля 2012

Да. Вы можете определить функцию вне класса, а затем использовать ее в теле класса как метод:

def func(self):
    print "func"

class MyClass(object):
    myMethod = func

Вы также можете добавить функцию в класс после того, как она была определена:

class MyClass(object):
    pass

def func(self):
    print "func"

MyClass.myMethod = func

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

Я бы отметил, что хотя это возможно в Python, это немного необычно. Вы упоминаете в комментарии, что «пользователям разрешено добавлять больше» методов. Это звучит странно. Если вы пишете библиотеку, вы, вероятно, не хотите, чтобы пользователи библиотеки динамически добавляли методы к классам в библиотеке. Для пользователей библиотеки более нормальным является создание своего собственного подкласса, который наследуется от вашего класса, чем непосредственное изменение вашего класса.

6 голосов
/ 11 октября 2016

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

class MyClass1(object):
    def __init__(self, bar):
        self.foo = 'updog'
        MyClass1.foobar = bar

class MyClass2(object):
    def __init__(self, bar):
        self.foo = 'updog'
        self.foobar = bar

def bar(self):
    return "What's " + self.foo

Давайте сначала посмотрим, что происходит в MyClass1foobar в этом классе похож на обычный метод, как если бы он был определен внутри определения класса (т. Е. Это метод, связанный с экземпляром этого класса).Давайте посмотрим, как это выглядит ...

In [2]: x = MyClass1(bar)

In [3]: x.foobar
Out[3]: <bound method MyClass1.bar of <__main__.MyClass1 object at 0x104346990>>

In [4]: x.foobar()
Out[4]: "What's updog"

Чем это отличается от MyClass2MyClass2, foobar является просто ссылкой на функцию бара и НЕ является связанным методом.Из-за этого мы должны передать экземпляр для правильной работы этой функции.например,

In [5]: y = MyClass2(bar)

In [6]: y.foobar
Out[6]: <function __main__.bar>

In [7]: y.foobar()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-6feb04878e5f> in <module>()
----> 1 y.foobar()

TypeError: bar() takes exactly 1 argument (0 given)

In [8]: y.foobar(y)
Out[8]: "What's updog"

Надеюсь, это так же ясно, как грязь ...

1 голос
/ 26 февраля 2012

Да, вы определенно можете иметь функции вне класса. Вот небольшой пример ...

def date_parse(date_string):
  return date(date_string)


class MyClass:
   def myFunc(self):
       pass

   def myDateFunc(self, date_string):
      self.date = date_parse(date_string)
0 голосов
/ 26 февраля 2012

Я даю снимок на то, что вы ищете, где один класс Helper предоставляет функции для специализированного класса (MyClass)

class Helper(object):

    def add(self, a, b):
        return a + b

    def mul(self, a, b):
        return a * b


class MyClass(Helper):

    def __init__(self):
        Helper.__init__(self)
        print self.add(1, 1)


if __name__ == '__main__':
    obj = MyClass()

Это напечатает

>>> 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...