2016-06-14 110 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

是的,在我上面的例子中,第一个版本的输出为'[]',第二个版本为'[]''。 –