Добавить метод к загружаемому классу/модулю в python

если у меня что-то вроде

import mynewclass

Можно ли добавить какой-то метод в mynewclass? Что-то вроде следующего в концепции:

def newmethod(self,x):
    return x + self.y

mynewclass.newmethod = newmethod

(я использую CPython 2.6)

Ответ 1

В Python оператор import используется для модулей, а не классов... поэтому для импорта класса вам нужно что-то вроде

from mymodule import MyClass

Более подробно о вашем вопросе ответ да. В классах Python используются только обычные объекты, а метод класса - это просто функция, хранящаяся в атрибуте объекта.

Атрибуты экземпляров объектов в Python, кроме того, являются динамическими (вы можете добавлять новые атрибуты объекта во время выполнения), и этот факт в сочетании с предыдущим означает, что вы можете добавить новый метод к классу во время выполнения.

class MyClass:
    def __init__(self, x):
        self.x = x

...

obj = MyClass(42)

def new_method(self):
    print "x attribute is", self.x

MyClass.new_method = new_method

obj.new_method()

Как это работает? При вводе

obj.new_method()

Python сделает следующее:

  • найдите new_method внутри объекта obj.

  • Не обнаруживая его как атрибут экземпляра, он попытается найти внутри объекта класса (который доступен как obj.__class__), где он найдет эту функцию.

  • Теперь есть немного обмана, потому что Python заметит, что найденная функция и, следовательно, "обернет" ее в закрытии, чтобы создать так называемый "связанный метод" ". Это необходимо, потому что, когда вы вызываете obj.new_method(), вы хотите вызвать MyClass.new_method(obj)... другими словами, привязка функции к obj для создания связанного метода - это то, что заботится о добавлении параметра self.

  • Этот связанный метод - это то, что возвращается obj.new_method, и тогда это будет окончательно вызвано из-за окончания () на этой строке кода.

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

Ответ 2

Да, если это тип Python. Кроме того, что вы делаете это в классе, а не в модуле/пакете.