2012-02-26 2 views
30
class MyClass: 
    def myFunc(self): 
     pass 

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

+1

Да ... вы можете определить функцию, где вы хотите (почти), но для какой цели? Чего вы хотите достичь? Обратите внимание, что функция в классе отличается от функции снаружи, например., использование параметра self, который ссылается на экземпляр, созданный функцией в – aweis

+0

Функции слишком велики. И пользователям разрешено добавлять больше. «Класс» в основном представляет собой контейнер полезных вспомогательных функций. –

+0

Похоже, вы работаете с наследованием, где один класс содержит список «вспомогательных» функций. Тогда другой класс может реализовать этот класс и использовать из него функции! – aweis

ответ

51

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

def func(self): 
    print "func" 

class MyClass(object): 
    myMethod = func 

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

class MyClass(object): 
    pass 

def func(self): 
    print "func" 

MyClass.myMethod = func 

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

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

+0

Есть ли более короткий способ добавить функцию в класс после ее объявления? Потому что это не кажется более простым/чистым, чем просто определение его внутри него (не то, что я знаю, это должно быть) –

+0

Конечно, если вы хотите, чтобы он был чистым и простым, просто объявите его внутри класса. Возможность добавления функции после класса была определена довольно эзотерически и, вероятно, в основном используется в сложных ситуациях, которые по какой-то причине должны создавать целые новые классы во время выполнения. Не могли бы вы лучше описать, что именно вы пытаетесь сделать: почему у вашего класса есть так много больших методов, которые вы хотите поместить в отдельные файлы? – Weeble

+0

Забудьте о «другом модуле». Основная причина, по которой я хотел иметь их вне определения фактического класса, заключалась в том, чтобы не иметь отступов для всех (около 80). Я думал, что это «чище». В противном случае кажется более чистым иметь функции внутри модуля, чем создавать класс с 80 функциями. –

-3

не уверен, если он подходит вам сценарию, но вы можете получить от MyClass и добавить функцию, которую вы хотите.

0

Я даю стрелять на то, что вы ищете, где один класс 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 
1

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

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

Нет, я имею в виду, могу ли я определить метод класса вне класса? –

3

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

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 

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

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" 

Как это отличается от MyClass2? В MyClass2, 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" 

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

Смежные вопросы