簡體   English   中英

使用其他一些類定義,使用不同的默認參數創建一個新的類定義?

[英]Create a new class definition with different default arguments, using some other class definition?

說我在Python 2.7中有以下類:

class X():
    def __init__(self, alpha=1):
        self.alpha = alpha
        print self.alpha

    def beta(self, gamma=1):
        self.gamma = gamma
        self.omega = self.alpha + self.gamma
        print self.omega

我想使用類定義來創建另一個具有不同默認參數的類定義,例如:

Y = f(X, alpha=2, gamma=2)

要么

Y = f(X, __init__.alpha=2, beta.gamma=2)

應該等於:

class Y():
    def __init__(self, alpha=2):
        self.alpha = alpha
        print self.alpha

    def beta(self, gamma=2):
        self.gamma = gamma
        self.omega = self.alpha + self.gamma
        print self.omega

是否可以在Python 2.7(或3)中做類似的事情?

(我知道您可以使用functools.partial對功能進行等效操作;因此,我想知道類是否存在類似的功能)

您可以編寫一個為您創建類的函數:

def makeclass(alpha, gamma):
    class C():
        def __init__(self, alpha=alpha):
            self.alpha = alpha
            print self.alpha

        def beta(self, gamma=gamma):
            self.gamma = gamma
            self.omega = self.alpha + self.gamma
            print self.omega

    return C
>>> X = makeclass(1, 1)
>>> Y = makeclass(2, 2)
>>> x = X() # X is the class, x is an instance
1
>>> x.beta()
2
>>> y = Y()
2
>>> y.beta()
4

可以做到,但是有點混亂。

這段代碼:

class Foo(base1, base2, ...):
    bar = something
    baz = something_else
    def qux(self):
        ...

...相當於此代碼,但是如果Foo是經典類,我不確定這是否正確:

Foo = type('Foo', (base1, base2, ...), {'bar': something, 'baz': something_else,
                                        'qux': lambda self: ...})

因此,我們可以即時創建類,並將自定義方法對象附加到它們。

對於您的特定情況,我們需要進行這些調用(假設您通過從object繼承將X轉換為新樣式的類)。 首先,我們從X提取方法並應用functools.partial

new_init = functools.partial(X.__init__.im_func, # Just X.__init__ in 3.x
                             alpha=2)
new_beta = functools.partial(X.beta.im_func, # Just X.beta in 3.x
                             gamma=2)

im_func屬性im_func綁定的方法對象中獲取底層函數。 在Python 3中,沒有諸如未綁定方法之類的東西,因此我們不需要使用此屬性。 X.__init__只是函數本身。

接下來,我們創建類:

Y = type('Y', (object,), {'__init__': new_init, 'beta': new_beta})

不幸的是,我們沒有任何合理的方法來獲取我們需要在此處重新定義的功能列表。 如果使用dir()我們將獲得許多不相關的特殊屬性。 我們可以使用該類的__dict__ ,但這將不包括任何繼承的方法。 我認為我們可能需要搜索X.__mro__以獲取方法的完全正確列表:

result = {}
for class_ in X.__mro__:
    for name, value in class_.__dict__.items():
        if name not in result:
            result[name] = value

我們還需要弄清楚每種情況下要覆蓋哪些參數。 inspect.getargspec()是一個很好的起點,但是,如果任何方法都是可變參數的(例如,它們采用*args**kwargs參數),它都無濟於事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM