Python: Разрешение методов, не конкретно определенных, чтобы быть названным крылом __ getattr __

Я пытаюсь записать класс Python, который имеет способность сделать следующее:

c = MyClass()
a = c.A("a name for A") # Calls internally c.create("A", "a name for A")
b = c.B("a name for B") # Calls internally c.create("B", "a name for B")

A и B мог быть чем-либо (хорошо, они определяются в базе данных, но я не хочу явно определять их в своем коде),

hacky обходное решение для него должно было бы сделать следующее:

class MyClass():
    def __init__(self):
        self.createItem = ""

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def create_wrapper(self, name):
        self.create(self.createItem, name)

    def __getattr__(self, attrName):
        self.createItem = attrName
        return self.create_wrapper

Это будет работать когда вызовы пользователя что-то как:

a = c.A("nameA")
b = c.B("nameB")

Однако это упадет в ситуациях, где указатели функции хранятся без того, чтобы быть названным:

aFunc = c.A
bFunc = c.B
aFunc("nameA") # Is actually calling c.create("B", "nameA"),
               # as c.B was the last __getattr__() call
bFunc("nameB")

Какие-либо предложения для чего-нибудь я отсутствую здесь?

Спасибо

Править: Я, кажется, только что понял этого, но у Philipp есть намного более изящное решение....

Мое решение было:

class MyClassCreator():
    def __init__(self, origClass, itemType):
        self.origClass = origClass
        self.itemType = itemType

    def create_wrapper(self, name):
        return self.origClass.create(self.itemType, name)

class MyClass():
    def __init__(self):
        self.createItem = ""

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        return MyClassCreator(self, attrName).create_wrapper

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

def __getattr__(self, attrName):
    def find_entity_wrapper(*args, **kwargs):
        return self.find_entity(attrName, *args, **kwargs)

    return find_entity_wrapper
5
задан Hugh 8 August 2010 в 16:32
поделиться