2

Bunch_methods.py として束のメソッドを含むファイルがあるとします。

def one(x):
  return int(x)

def two(y)
  return str(y)

モジュール全体をインポートするか、メソッドを選択して、そのメソッドのグループを取得し、インポートしたものをクラスに変換する方法はありますか?

例: 擬似的に

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 = make_class_from_module(bunch_methods)

私の考えでは正当に聞こえますが、それはどの程度実行可能ですか? このようなことを始めるにはどうすればよいでしょうか。

なぜ私はこれをしたいのですか?今のところ、それは精神的および学習的な演習ですが、私の具体的な使用方法は、メソッドを取得してフラスコクラスの FlaskView クラスを作成することです。メソッドのグラブバッグを潜在的に取得し、FlaskView を使用して異なるコンテキストでそれらを潜在的に使用および再利用したいと思います


4

4 に答える 4

2

lambdaこれは、あなたが望むことを実行できるシンプルな(しかし長い)ワンライナーです(部分的にBakuriuに触発されました)。

classify = lambda module: type(module.__name__, (), {key: staticmethod(value) if callable(value) else value for key, value in ((name, getattr(module, name)) for name in dir(module))})

次の関数の方が読みやすく、内包表記でループが見やすいかもしれません。

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
>>> 

補遺:

モジュールをクラスに変換する使用方法の 1 つを認識した後、変換されたモジュールを基底クラスとして使用する方法を示す次のサンプル プログラムが作成されました。このパターンは一般的な使用にはお勧めできないかもしれませんが、この概念の興味深い応用例を示しています。関数は、classify以下に示すバージョンでも読みやすくなっているはずです。

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()
于 2013-05-23T16:31:16.067 に答える
1

なぜこれをしたいのかわかりませんが、簡単なアプローチは次のようになります。

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

ただし、これ以上のことを行うのは非常に困難で醜いものになり、これを行うには本当に正当な理由が必要です。そうしないと、無駄な労力になります。

于 2013-05-23T15:17:18.533 に答える
1

この問題は、typeメタクラスを使用して解決することもできます。を使用してクラスを生成するための形式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)

これをbunk_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'

メタクラスに関する優れた (そして長い) ガイドについては、次の投稿を参照してください。 Python のメタクラスとは何ですか?

于 2013-05-23T15:39:12.483 に答える
0

モジュールをクラスとして既に使用できるため、なぜこれが必要なのかわかりませんが、とにかく:

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)
于 2013-05-23T15:20:16.640 に答える