以编程方式将模块/函数集转换为Python类

以编程方式将模块/函数集转换为Python类,python,class,function,methods,module,Python,Class,Function,Methods,Module,假设我有一个文件,其中包含一个bunch方法作为bunch_methods.py: def one(x): return int(x) def two(y) return str(y) 有没有一种方法可以通过导入模块整体或select方法来获取该组方法,并将导入的方法转换为类 e、 伪明智 def make_class_from_module(which_module_or_listing_of_methods): class = turn_module_to_class(w

假设我有一个文件,其中包含一个bunch方法作为bunch_methods.py:

def one(x):
  return int(x)

def two(y)
  return str(y)
有没有一种方法可以通过导入模块整体或select方法来获取该组方法,并将导入的方法转换为类

e、 伪明智

def make_class_from_module(which_module_or_listing_of_methods):
    class = turn_module_to_class(which_module_or_listing_of_methods)
    return class
所以

BunchClass=从_模块生成_类(bunch_方法)

在我看来这是合法的,但它有多可行?如果我应该这样做,我将如何开始做这样的事情,或者我的选择是什么

我为什么要这么做?现在这是一个心理和学习练习,但我心目中的具体用途是采取方法和创造。我想用FlaskView在不同的上下文中潜在地使用和重用一些方法



不知道为什么要这样做,但一个简单的方法可以是:

def to_class(module):
    class TheClass(object): pass
    for attr in dir(module):
        val = getattr(module, attr)
        if callable(val):
            setattr(TheClass, attr, staticmethod(val))
    return TheClass
用法:

>>> import math
>>> Math = to_class(math)
>>> m = Math()
>>> m.sin(5)
-0.9589242746631385
>>> math.sin(5)
-0.9589242746631385
>>> Math.sin(5)
-0.9589242746631385
如果模块也有一些变量,您可以对其进行增强,将不可调用的对象也添加到类中:

def to_class(module):
    class TheClass(object): pass
    for attr in dir(module):
        val = getattr(module, attr)
        if callable(val):
            setattr(TheClass, attr, staticmethod(val))
        else:
            setattr(TheClass, attr, val)
    return TheClass

然而,做更多的事情会变得非常困难和丑陋,你必须有一个很好的理由这样做,否则这是浪费精力。

不知道你为什么要这样做,但一个简单的方法可以是:

def to_class(module):
    class TheClass(object): pass
    for attr in dir(module):
        val = getattr(module, attr)
        if callable(val):
            setattr(TheClass, attr, staticmethod(val))
    return TheClass
用法:

>>> import math
>>> Math = to_class(math)
>>> m = Math()
>>> m.sin(5)
-0.9589242746631385
>>> math.sin(5)
-0.9589242746631385
>>> Math.sin(5)
-0.9589242746631385
如果模块也有一些变量,您可以对其进行增强,将不可调用的对象也添加到类中:

def to_class(module):
    class TheClass(object): pass
    for attr in dir(module):
        val = getattr(module, attr)
        if callable(val):
            setattr(TheClass, attr, staticmethod(val))
        else:
            setattr(TheClass, attr, val)
    return TheClass

然而,做更多的事情会变得非常困难和丑陋,你必须有一个很好的理由这样做,否则这是浪费精力。

我不知道你为什么想要这样做,因为你已经可以将模块作为一个类来使用了,但无论如何:

import bunch_methods as bm

print bm.one('1')
print bm.two(1)

class BunchClass:
    def __init__(self, methods):
        self.__dict__.update(methods.__dict__)

bc = BunchClass(bm)

print bc.one('2')
print bc.two(2)

我不知道您为什么想要这个,因为您已经可以将模块作为类使用,但无论如何:

import bunch_methods as bm

print bm.one('1')
print bm.two(1)

class BunchClass:
    def __init__(self, methods):
        self.__dict__.update(methods.__dict__)

bc = BunchClass(bm)

print bc.one('2')
print bc.two(2)

您还可以使用
类型
元类解决此问题。使用
type
生成类的格式如下:

type(name of the class, 
   tuple of the parent class (for inheritance, can be empty), 
   dictionary containing attributes names and values)
首先,我们需要重新编写函数,将类作为第一个属性

def one(cls, x):
    return int(x)

def two(cls, y):
    return str(y)
将其另存为bunch_method.py,现在我们可以如下构造我们的类

>>> import bunch_methods as bm
>>> Bunch_Class = type('Bunch_Class', (), bm.__dict__)
>>> bunch_object = Bunch_Class()
>>> bunch_object.__class__
<class '__main__.Bunch_Class'>
>>> bunch_object.one(1)
1
>>> bunch_object.two(1)
'1'
>>将bunch\u方法导入为bm
>>>Bunch_Class=类型('Bunch_Class',(),bm.\uu dict\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
>>>bunch\u对象=bunch\u类()
>>>束对象__
>>>一(1)
1.
>>>束_对象。二(1)
'1'

有关元类的优秀(长)指南,请参见下面的文章

您还可以使用
类型
元类解决此问题。使用
type
生成类的格式如下:

type(name of the class, 
   tuple of the parent class (for inheritance, can be empty), 
   dictionary containing attributes names and values)
首先,我们需要重新编写函数,将类作为第一个属性

def one(cls, x):
    return int(x)

def two(cls, y):
    return str(y)
将其另存为bunch_method.py,现在我们可以如下构造我们的类

>>> import bunch_methods as bm
>>> Bunch_Class = type('Bunch_Class', (), bm.__dict__)
>>> bunch_object = Bunch_Class()
>>> bunch_object.__class__
<class '__main__.Bunch_Class'>
>>> bunch_object.one(1)
1
>>> bunch_object.two(1)
'1'
>>将bunch\u方法导入为bm
>>>Bunch_Class=类型('Bunch_Class',(),bm.\uu dict\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
>>>bunch\u对象=bunch\u类()
>>>束对象__
>>>一(1)
1.
>>>束_对象。二(1)
'1'
有关元类的优秀(长)指南,请参见下面的文章

这里有一个简单(但很长)的单行程序
lambda
,它可以做你想做的事(部分灵感来自巴库留)

您可能会发现以下函数更容易阅读,并且在理解中更容易看到循环

def classify(module):
    return type(module.__name__, (),
                {key: staticmethod(value) if callable(value) else value
                 for key, value in ((name, getattr(module, name))
                                    for name in dir(module))})
这种用法实际上与巴库留的答案相同,正如你在与口译员交谈时看到的那样

>>> import math
>>> MathClass = classify(math)
>>> MathClass.sin(5)
-0.9589242746631385
>>> instance = MathClass()
>>> instance.sin(5)
-0.9589242746631385
>>> math.sin(5)
-0.9589242746631385
>>> 

附录:

在实现了将模块转换为类的一种用途之后,编写了以下示例程序,说明如何将转换后的模块用作基类。该模式可能不推荐用于常见用途,但确实显示了该概念的有趣应用。在如下所示的版本中,
分类
功能也应该更易于阅读

import math


def main():
    print(Point(1, 1) + Point.polar(45, Point.sqrt(2)))


def classify(module):
    return type(module.__name__, (), {
        key: staticmethod(value) if callable(value) else value
        for key, value in vars(module).items()
    })


class Point(classify(math)):

    def __init__(self, x, y):
        self.__x, self.__y = float(x), float(y)

    def __str__(self):
        return str((self.x, self.y))

    def __add__(self, other):
        return type(self)(self.x + other.x, self.y + other.y)

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @classmethod
    def polar(cls, direction, length):
        radians = cls.radians(direction)
        x = round(cls.sin(radians) * length, 10)
        y = round(cls.cos(radians) * length, 10)
        return cls(x, y)


if __name__ == '__main__':
    main()
这里有一个简单(但很长)的单行程序
lambda
,它可以做你想做的事情(部分灵感来自巴库留)

您可能会发现以下函数更容易阅读,并且在理解中更容易看到循环

def classify(module):
    return type(module.__name__, (),
                {key: staticmethod(value) if callable(value) else value
                 for key, value in ((name, getattr(module, name))
                                    for name in dir(module))})
这种用法实际上与巴库留的答案相同,正如你在与口译员交谈时看到的那样

>>> import math
>>> MathClass = classify(math)
>>> MathClass.sin(5)
-0.9589242746631385
>>> instance = MathClass()
>>> instance.sin(5)
-0.9589242746631385
>>> math.sin(5)
-0.9589242746631385
>>> 

附录:

在实现了将模块转换为类的一种用途之后,编写了以下示例程序,说明如何将转换后的模块用作基类。该模式可能不推荐用于常见用途,但确实显示了该概念的有趣应用。在如下所示的版本中,
分类
功能也应该更易于阅读

import math


def main():
    print(Point(1, 1) + Point.polar(45, Point.sqrt(2)))


def classify(module):
    return type(module.__name__, (), {
        key: staticmethod(value) if callable(value) else value
        for key, value in vars(module).items()
    })


class Point(classify(math)):

    def __init__(self, x, y):
        self.__x, self.__y = float(x), float(y)

    def __str__(self):
        return str((self.x, self.y))

    def __add__(self, other):
        return type(self)(self.x + other.x, self.y + other.y)

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @classmethod
    def polar(cls, direction, length):
        radians = cls.radians(direction)
        x = round(cls.sin(radians) * length, 10)
        y = round(cls.cos(radians) * length, 10)
        return cls(x, y)


if __name__ == '__main__':
    main()

你为什么要这个?所有函数都没有任何状态(如您所示),因此在这里创建类实际上没有任何目的。您打算如何处理此类?要补充@mgilson所说的,模块已经是
模块
类型的类的实例。将无状态函数的容器类与另一个容器类一起包装或转换成另一个容器类会有什么价值?我不认为
flask classy
是这样做的理由。我怀疑这是用这样的东西实现的。在思考了一段时间为什么会有人想这样做之后,我突然意识到将模块转换为类允许类继承。该模式可能不值得推荐,但它确实是一个选项。为什么要这样?所有函数都没有任何状态(如您所示),因此在这里创建类实际上没有任何目的。您打算如何处理此类?要补充@mgilson所说的,模块已经是
模块
类型的类的实例。将无状态函数的容器类与另一个容器类一起包装或转换成另一个容器类会有什么价值?我不认为
flask classy
是这样做的理由。我怀疑这是用这样的东西实现的。在思考了一段时间为什么会有人想这样做之后,我突然意识到将模块转换为类允许类继承。这种模式可能不可取,但肯定是一种选择。这是错误的。OP希望将模块转换为新类。你的密码转换器