EDIT:より良い解決策は、参照してください以下のセクションで説明します。
必要に応じて、dir
のクラスを検索せず、すべてfind_methods
の呼び出しごとに検索することができます。これは、私がタグ付け機能をよりスマートにし、それらを追加して辞書に格納するときにタグ付き機能のリストを構築する場合です。 Find_methodsは辞書から関数リストを取得するだけです。
例えば
class Tagger(object):
def __init__(self):
self._dict = {}
def __call__(self, name):
if name not in self._dict:
self._dict[name] = []
def tags_decorator(func):
self._dict[name].append(func)
func._tag = name
return func
return tags_decorator
tag = Tagger()
class ExampleClass:
@tag('foo')
def method_a(self):
"""does stuff"""
@tag('foo')
def method_b(self):
"""does stuff"""
def method_c(self):
"""does stuff"""
@tag('bar')
def method_d(self):
"""does stuff"""
@tag('bar')
def method_e(self):
"""does stuff"""
print(tag._dict)
ORIGINAL POST:最終溶液の説明。
私は他の誰かから与えられたアイデアを拡張しますが、削除されました。彼はすべての機能のプライベート属性_tag
を追加することを提案しました。 Pythonのすべてがオブジェクトなので、これを行うことができます。だから、
:
class ExampleClass:
# category: foo
def method_a(self):
"""does stuff"""
method_a._tag = "foo"
それはしかし汚いコードなので、多分私たちはより良い行うことができますか?例えば。関数でタグ付けすることができます。
def add_foo_tag(func):
func._tag = "foo"
return func
class ExampleClass:
# category: foo
def method_a(self):
"""does stuff"""
method_a = add_foo_tag(method_a)
しかし、我々はまだ良く行うことができます。
class ExampleClass:
# category: foo
@add_foo_tag
def method_a(self):
"""does stuff"""
しかし、どのような他のタグ文字列で:デコレータが私たちのためにmethod_a = add_foo_tag(method_a)
を呼ぶであろう、そのため@
を構文がありますか?タグデコレータ工場を作ろう!
def tag(tag_name):
def tags_decorator(func):
func._tag = tag_name
return func
return tags_decorator
と構文がいいです。今
class ExampleClass:
@tag('foo')
def method_a(self):
"""does stuff"""
@tag('foo')
def method_b(self):
"""does stuff"""
def method_c(self):
"""does stuff"""
@tag('bar')
def method_d(self):
"""does stuff"""
@tag('bar')
def method_e(self):
"""does stuff"""
、どのようなクラスのメソッドを見つけると?使用できる操作はdir
です。コードの明示的なバージョンがあります:
def find_methods_explicit(cls, label):
"""Searches through the class namespace
returns all methods with the correct label"""
attributes = [getattr(cls, func) for func in dir(cls)]
tagged = [attr for attr in attributes if '_tag' in dir(atrr)]
labeled = [attr for attr in tagged if atrr._tag == label]
return labeled
とワンライナー:
def find_methods(cls, label):
"""Searches through the class namespace
returns all methods with the correct label"""
return [getattr(cls, func) for func in dir(cls) if '_tag' in dir(getattr(cls, func)) and getattr(cls, func)._tag == label]
最後に、用法:
print(ExampleClass.method_a._tag)
print(find_methods(ExampleClass,'foo'))
print(find_methods(ExampleClass,'bar'))
print(find_methods(ExampleClass,'qwe'))
全コード:
def tag(tag_name):
def tags_decorator(func):
func._tag = tag_name
return func
return tags_decorator
class ExampleClass:
@tag('foo')
def method_a(self):
"""does stuff"""
@tag('foo')
def method_b(self):
"""does stuff"""
def method_c(self):
"""does stuff"""
@tag('bar')
def method_d(self):
"""does stuff"""
@tag('bar')
def method_e(self):
"""does stuff"""
def find_methods(cls, label):
"""Searches through the class namespace
returns all methods with the correct label"""
return [getattr(cls, func) for func in dir(cls) if '_tag' in dir(getattr(cls, func)) and getattr(cls, func)._tag == label]
print(ExampleClass.method_a._tag)
print(find_methods(ExampleClass,'foo'))
print(find_methods(ExampleClass,'bar'))
print(find_methods(ExampleClass,'qwe'))
とオンライン例:https://repl.it/repls/FrayedMilkyKangaroo
この関数は、メソッド名が特定の名前と等しいかどうかをチェックします。私が気にするのは、メソッド名に特定の名前のタグが付いているかどうかです。メソッド名自体は何でもかまいません。 –
タグはどのくらいの頻度で変更されますか? @ K.Mao – Philip556677
非常にまれです。前にも述べたように、メソッドとタグをマップする変数をクラスの先頭に含めることができます。しかし、これは維持するのがより難しく、ExampleClassを継承し、子クラスに追加のタグを持っていると、特に面倒です。 –