2016-06-14 112 views
0

我已經實現了一個類BasicForm,還包含一個方法__str__能夠打印的東西。我也有一個函數stringToBasicForm(string)將某些類型的字符串轉換爲BasicForm對象。Python自動轉換數據類型

在我的計劃之後,我允許字符串數組array,我做到以下幾點:

for i in xrange(len(array)): 
    array[i] = stringToBasicForm(array[i]) 

我的問題是,在此之後,array似乎包含str類型的對象,而不是按照我的預期鍵入BasicForm。我認爲Python出於某種原因自動將我的BasicForms轉換爲使用__str__的字符串。

發生了什麼事?我怎樣才能讓我的數組在最後包含好類型的對象(不需要創建輔助數組)?

任何幫助將不勝感激。

備註:我使用Python 2.7


這裏有一個小十歲上下的工作例如:

from fractions import * 
from numpy import * 

class BasicForm: 

    def __init__(self,n,coeff,I): 

     if shape(I)[1] != n + 1: 
      print "Error: illegal I." 
      return 
     if not all([isinstance(f,Fraction) for f in coeff]): 
      print "Error: coefficients must be of class Fraction." 
      return 

     self.n = n 

     vect = zeros(2**(n+1)-1,dtype = Fraction) 
     for i in xrange(len(I)): 
      if not any(I[i]): 
       print "Error: the empty set doesn't code any basic form." 
       return 
     vect[subsetToIndex(n,I[i])] = coeff[i] 
     self.vect = vect 

    def __str__(self): 

     if not any(self.vect): 
      return "0" 

     s = "" 
     first = True 
     for i in xrange(2**(self.n+1)-1): 
      if self.vect[i] == 0: 
       continue 
      if self.vect[i] < 0: 
       s += "-" 
       if not first: 
        s = s[:-3] + "- " 
      if self.vect[i] != 1: 
       s += str(abs(self.vect[i])) + "*" 
      s += "(" 
      I = indexToSubset(self.n,i) 
      for k in xrange(self.n+1): 
       if I[k]: 
        s += str(k) 
      s += ") + " 
      first = False 

     return s[:-2] 

def stringToBasicForm(n,string): 

    out = BasicForm(n,[Fraction(0)],[ones(n+1,dtype = bool)]) 

    return out 

現在的怪異的一部分。如果我運行這個

n = 1 
array = ["(01)"] 
for i in xrange(len(array)): 
    array[i] = stringToBasicForm(n,array[i]) 
    print isinstance(array[i],BasicForm), isinstance(array[i],str) 

一切都按預期工作(輸出:True False)。但是,如果我有

def opPBT(n,LPBT,BF_array): 

    tree = copy(LPBT) 
    array = copy(BF_array) 

    # Convert basic forms to elements to the Sullivan algebra (injection). 
    for i in xrange(len(array)): 
     if isinstance(array[i],str): 
      array[i] = stringToBasicForm(n,array[i]) 
      print isinstance(array[i],BasicForm), isinstance(array[i],str) 
     elif array[i].n != n: 
      print "Error: basic form of wrong dimension." 
      return 
     array[i] = basicToSullivan(array[i]) 
    return 

n = 2 
forms = ["(01)"] 
lcomb = [] 
opPBT(n,lcomb,forms) 

這是運行它,我想做些什麼,那麼輸出爲False True,我也完全不知道我做錯了什麼(它可能是一些愚蠢的錯誤,但我會被定罪,如果我能看到它... ...)

+0

'stringToBasicForm'做什麼? – timakro

+0

不,Python不會像那樣使用for循環來完成自身的轉換。我們想看看你的stringToBasicForm函數。 – RemcoGerlich

+0

@timakro它將某些字符串轉換爲'BasicForm'。它沒有問題,並返回正確的數據類型。 –

回答

2

numpy的陣列強類型

>>> x = np.empty((3,), dtype=np.float64) 
>>> x[0] = 1 # I put an int in... 
>>> x[0]  # And get a float out ! 
1.0 

一般情況下,陣列將嘗試傳遞值轉換成(這是你想要的通常是什麼,參照上面的例子,你不希望整個事情崩潰,因爲你忘記之後. 10)。既然你有一個方便的__str__,它將使用它來確保你的數組是一致的。

這與您的問題有什麼關係?我懷疑你正在使用的copy是numpy的副本:

>>> from numpy import copy 
>>> copy([1,2,3]) # List in, array out... 
array([1, 2, 3]) 

這可以解釋你的自動強制;正常的Python列表並不像這樣操作:

>>> foo = ['a', 'b', 'c'] 
>>> class A(object): 
...  def __str__(self): 
...   return "converted !" 
... 
>>> bar = copy(foo) 
>>> bar[0] = A() 
>>> foo[0] = A() 
>>> type(foo[0]) 
__main__.A 
>>> type(bar[0]) 
numpy.string_ 
>>> isinstance(bar[0], str) 
True 
+0

這是問題所在。謝謝你,我永遠不會發現自己。 –

0

關於你stringToBasicForm函數的返回值必須是無或BasicForm實例...

你能只是類型檢查()?

class BasicForm: 
def __init__(self, s): 
    pass 

def __str__(self): 
    return "PLOP" 

array = ['toto', 'tata', 'tutu'] 

print([type(elem) for elem in array]) 

for i, elem in enumerate(array): 
    array[i] = BasicForm(elem) 

print([type(elem) for elem in array]) 

輸出:

[<class 'str'>, <class 'str'>, <class 'str'>] 
[<class '__main__.BasicForm'>, <class '__main__.BasicForm'>, <class '__main__.BasicForm'>] 
+0

是的,在我上面的例子中,第一個版本的輸出爲'[]',第二個版本爲'[]''。 –