gpt4 book ai didi

Python 在 __new__ 方法中检查可迭代

转载 作者:太空宇宙 更新时间:2023-11-03 11:08:31 28 4
gpt4 key购买 nike

我正在尝试编写一个 python (2.7) 矩阵模块。 (我知道 numpy,这只是为了好玩。)

我的代码:

from numbers import Number
import itertools

test2DMat = [[1,2,3],[4,5,6],[7,8,9]]
test3DMat = [[[1,2,3],[4,5,6],[7,8,9]],[[2,3,4],[5,6,7],[8,9,0]],[[9,8,7],[6,5,4],[3,2,1]]]

class Dim(list):
def __new__(cls,inDim):
# If every item in inDim is a number create a Vec
if all(isinstance(item,Number) for item in inDim):
#return Vec(inDim)
return Vec.__new__(cls,inDim)

# Otherwise create a Dim
return list.__new__(cls,inDim)

def __init__(self,inDim):
# Make sure every item in inDim is iterable
try:
for item in inDim: iter(item)
except TypeError:
raise TypeError('All items in a Dim must be iterable')

# Make sure every item in inDim has the same length
# or that there are zero items in the list
if len(set(len(item) for item in inDim)) > 1:
raise ValueError('All lists in a Dim must be the same length')

inDim = map(Dim,inDim)
list.__init__(self,inDim)


class Vec(Dim):
def __new__(cls,inDim):
if cls.__name__ not in [Vec.__name__,Dim.__name__]:
newMat = list.__new__(Vec,inDim)
newMat.__init__(inDim)
return newMat
return list.__new__(Vec,inDim)

def __init__(self,inDim):
list.__init__(self,inDim)


class Matrix(Dim):
def __new__(cls,inMat):
return Dim.__new__(cls,inMat)

def __init__(self,inMat):
super(Matrix,self).__init__(inMat)

当前功能:

到目前为止,我已经编写了几个类,MatrixDimVecMatrixVec 都是Dim 的子类。创建矩阵时,首先会从列表列表开始,然后创建如下矩阵:

>>> startingList = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix.Matrix(startingList)
[[1,2,3],[4,5,6],[7,8,9]]

这应该创建一个矩阵。创建的 Matrix 应该包含多个长度相同的 Dim。这些 Dim 中的每一个都应该包含多个长度相同的 Dim,等等。最后一个包含数字的 Dim 应该只包含数字,应该是 Vec 而不是 Dim

问题:

所有这些都适用于列表。但是,如果我使用迭代器对象(例如 iter() 返回的对象),则它不会像我希望的那样运行。

例如:

>>> startingList = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix.Matrix(iter(startingList))
[]

我的想法:

我相当确定这会发生,因为在 Dim.__new__ 中我迭代输入可迭代对象,当相同的可迭代对象被传递给 Matrix.__init__它已经被迭代过,因此看起来是空的,导致我得到空矩阵。

我已经尝试使用 itertools.tee() 复制迭代器,但这也不起作用,因为我实际上并没有调用 Matrix.__init__ 它被调用了当 Matrix.__new__ 返回时隐式地调用它,因此我不能使用与传递给 Matrix.__init__ 的参数不同的参数来调用它。我想做的一切都遇到了同样的问题。

有什么方法可以让我保留现有功能并允许使用迭代器对象调用 matrix.Matrix()

最佳答案

关键是 Vec.__init__ 被调用了两次;一次在你的 __new__ 方法中,一次当你从 __new__ 方法返回它时。因此,如果您将其标记为已初始化并从 Vec.__init__ 提前返回(如果它已初始化),那么您可以忽略第二次调用:

class A(object):
def __new__(cls, param):
return B.__new__(cls, param + 100)
class B(A):
def __new__(cls, param):
b = object.__new__(B)
b.__init__(param)
return b
def __init__(self, param):
if hasattr(self, 'param'):
print "skipping __init__", self
return
self.param = param
print A(5).param

关于Python 在 __new__ 方法中检查可迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12958217/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com