#python-3.x
#python-3.x
Вопрос:
Я новичок в python. Я хочу написать метод add_function для этого класса, чтобы динамически добавлять любую функцию в мой класс. Эта функция может манипулировать некоторыми атрибутами моего класса, но она написана вне класса. Предположим, что это класс и его метод.
import numpy as np
import feature_function as ffun
class Features:
def __init__(self,x,fs=None):
self.x = x
self.fs = fs
self.label = []
self.features = []
def __mean(self, nan_omit = False, min_samples = 1):
out = ffun.mean(self.x, nan_omit = nan_omit, min_samples = min_samples)
self.label.extend(['mean'])
self.features = np.append(self.features,out)
теперь я хочу написать эту функцию за пределами класса:
def __max(self, nan_omit = False, min_samples = 1):
out = ffun.max(self.x, nan_omit = nan_omit, min_samples = min_samples)
self.label.extend(['max'])
self.features = np.append(self.features,out)
и добавьте ее в класс. Для добавления функции в класс у меня есть метод add_function внутри моего класса, аргументами которого являются функция, передаваемая за пределы класса, а также имя функции.
# Add function dynamically by user
def add_function(self, name, methodToRun, type ):
name2 = '__' name
# setattr(self, name2, methodToRun)
setattr(self, mangle_attr(self, name2), methodToRun)
mangle_attr
это функция для того, чтобы присвоить классу приватную функцию.
def mangle_attr(source, attr):
# if source is an object, get the class
if not hasattr(source, "__bases__"):
source = source.__class__
# mangle attr
tmp = {}
code = _mangle_template.format(cls=source.__name__, attr=attr)
eval(compile(code, '', 'exec'), {}, tmp);
return tmp['cls'].mangle.__code__.co_varnames[0]
использование setattr
не привязывает __max
функцию к моему классу, например, __mean
она ограничена в моем классе, если я вызываю функцию, я могу видеть:
<bound method Features.__mean of <__main__.Features object at 0x7fd4c91aac10>>
однако для __max
я все еще вижу это: <function skewness at 0x7fd2b9dbfb90>
есть ли у меня решение этой проблемы?
Комментарии:
1.
"now I want to write this function outside of the scope of class:"
почему? Она должна либо быть написана внутри класса, к которому она принадлежит, либо, если это может быть применимо к нескольким классам, быть записана внутри родительского класса, который затем подразделяется на подклассы.2. предположим, что сумасшедший пользователь моей программы, который хочет написать произвольную функцию, которая (возможно) манипулирует атрибутами моего класса, и он хочет, чтобы у моего класса был метод add_function, чтобы добавить его в мой класс.
3. Обратите внимание, что использование искаженных имен очень необычно. Основная цель — защитить детали реализации от переопределения при расширении класса, например, через подклассы. Это противоречит намеренному добавлению искаженных имен извне класса. Методы расширения обычно должны быть общедоступными по определению.
Ответ №1:
Ваш addfunction
аргумент привязывается к экземпляру self
, а не к классу. Привязать аргумент к классу, например, через type(self)
или classmethod
:
class Features:
...
# Add function dynamically by user
@classmethod
def add_function(cls, name, methodToRun, type ):
name2 = '__' name
setattr(cls, mangle_attr(self, name2), methodToRun)
Связанный метод — это функция в классе, просматриваемая через экземпляр. Добавление функции к экземпляру просто делает ее атрибутом, который, оказывается, можно вызывать.
Ответ №2:
Более простой пример, чтобы показать общую идею:
# Create the class without a method
class Features():
def __init__(self):
self.x = 100
# Create a function outside of the class
def multiply(self):
return self.x*2
# initialize class object, then add function as a method to the class
obj = Features()
setattr(Features, "multiply", multiply)
obj.multiply()
Комментарии:
1. Замена
setattr(Features, "multiply", multiply)
наFeatures.multiply = multiply
работает. Смотрите repl.it/repls/WretchedAzureAmoeba#main.py2. Ах, хаха, я глупый, я пытался использовать это для объекта, а не для класса. Вы правы! Есть ли какое-либо преимущество выбора одного над другим?