Python自动转换数据类型

时间:2016-06-14 14:30:42

标签: python python-2.7 type-conversion

我已经实现了一个类BasicForm,其中还包含一个方法__str__,可以打印内容。我还有一个函数stringToBasicForm(string)将某些类型的字符串转换为BasicForm对象。

稍后在我的程序中,我有一个允许字符串的数组array,我执行以下操作:

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

我的问题是,在此之后,array似乎包含类型str的对象,而不是我预期的类型BasicForm。我认为Python出于某种原因使用__str__自动将我的BasicForms转换为字符串。

发生了什么事?我怎样才能使我的数组在最后包含良好类型的对象(不创建辅助数组)?

非常感谢任何帮助。

备注:我正在使用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,我完全不知道我做错了什么(它可能是一些愚蠢的错误,但我和# 39;如果我能看到它就会被诅咒......)

2 个答案:

答案 0 :(得分: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

通常,数组会尝试转换您传入的值(这通常是您想要的,参见上面的示例,您不希望整个事情崩溃,因为您忘记了.之后1)。由于您有一个方便的__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

答案 1 :(得分:0)

关于stringToBasicForm函数,返回值必须为None或BasicForm实例...

您可以查看type()吗?

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'>]