2013-10-11 72 views
0

如何泡菜的對象的子類,但只能捕捉到它的超類的變量(和轉換對象超類)。的Python酸洗變量只有在超

的原因,我這樣做是因爲我有我需要創建我的「類」,但需要一個輕量版本時,我讀它的額外信息。

例子:

import cPickle 
def unpickle_me(filename): 
    myobj= cPickle.load(open(filename, "rb")) 
    return myobj 

def pickle_me(obj, filename): 
    cPickle.dump(obj, open(filename, "wb")) 

class A(object): 
    def __init__(self): 
     self.a = [] 

    def read_index(self, index): 
     return self.a[index] 

class B(A): 
    def __init__(self, b): 
     super(B, self).__init__() 
     self.b = b; # let b = 3 for example 

    def add_to_super(self, avar): 
     self.a.append(avar*self.b) 

classB = B(3) 
classB.add_to_super(5) 
pickle_me(classB, 'me_b.pickle') 
myobj = unpickle_me('me_b.pickle') 
print(type(myobj), myobj.__dict__) 
>>>> (<class '__main__.B'>, {'a': [15], 'b': 3}) 

所以酸洗作品!它醃製我所期望的。但在現實中,我希望更多的東西一樣:

pickle_me(classB, 'me_b.pickle') 
myobj = unpickle_me('me_b.pickle') 
print(type(myobj), myobj.__dict__) 
>>>> (<class '__main__.A'>, {'a': [15]}) # class A and only has A 

作爲獎勵,誰打開它無法「追加」雖然我的「add_to_super」另一個值至A。

問題: 1.有沒有辦法做到這一點?我願意寫__兩個A類和B類

  1. 如果我使用有getstate __ __ __有getstate信息,有沒有辦法自動不但節省我在A級分配變量?所以我不需要說出自我。 __ __字典[「B」]

  2. 我可以寫一個特殊的方法,可以讓我選擇我要的是哪個版本?像泡菜只是一個信息或鹹菜B信息(給B類時)

  3. 側面的問題:我需要在這種情況下定義__ setstate __嗎?或者單獨使用__ getstate __?

  4. 此外,我在這裏實現了結構OO很爛,也不會介意任何指針。

+0

我對OOP的指針 - 你'print'語法上看,你是使用Python 3.x的在Python 3.x.中,不需要從'object'繼承類。你只在Python 2.x中做到了這一點。使班級成爲「新式」班級。在Python 3.x中。然而,_all_類是「新風格」。 – iCodez

+0

@iCodez - 'cPickle'另一方面會提示python2 – mata

回答

0

我認爲最乾淨的解決辦法是B轉換爲A酸洗(如果你要醃僅A信息)前。

class B(A): 
    def to_A(self): 
     a = A() 
     a.a = self.a 
     return a 

然後,當你unpickle這一點,你會得到一個A爲你想要的。

對我來說,這樣的顯示解比寫看中酸洗界面更好。

關於您的要點#4(OO結構),您的B類被稱爲工廠。通常情況下,它是便於工廠有排序的API:

factory = MyFactory() 
factory.set_some_parameters(...) 
factory.set_some_other_parameters(...) 
A1 = factory.construct_A() 
A2 = factory.construct_A() 
+0

感謝您的回答Q4!我很高興這有點(?)標準做法!但是,僅僅重申問題1,在我的「construct_A()」中是否有一種方法可以自動檢測僅針對類A的變量,因此我不需要執行「aa = self.a」,並且如果添加更多變量「a.a1 = self.a1」來設置這些變量? – user1639926

+0

我的新版本的功能: 高清convert_to_superclass(個體經營): save_obj =自.__類__.__基地__() 在save_obj .__字典__鍵鍵(): save_obj .__ dict__ =自.__字典__ [關鍵] – user1639926

0

可以使用__reduce__協議指定什麼將被代替醃製類,__setstate____getstate__的實例總是在原來的操作類。所以,如果你想,只要你有B一個實例來醃製的A一個實例,它可能是這樣的:

class B(A): 
    def __init__(self, b): 
     super(B, self).__init__() 
     self.b = b; # let b = 3 for example 

    def add_to_super(self, avar): 
     self.a.append(avar*self.b) 

    def __reduce__(self): 
     return A,(), {'a': self.a} 
+0

在這情況下,我需要具體說明減少要保存的變量嗎?有沒有一種快速的方法只抓取超類中的變量?說如果我在A類中添加一個變量,它會「自動」停留在這裏。 – user1639926

+0

不,這不可能。在這種情況下'a'是一個實例變量,實例變量不屬於任何類,它們屬於實例。它在'A .__ init__'中創建並不重要,最後它只是實例'__dict__'中的另一個條目。 – mata