首页 > 解决方案 > Python类方法:对象没有属性+对象不可下标

问题描述

class elem:
    def __init__(self, coords):
        if not coords.shape == (2, 3):
            raise TypeError("")
    def Jac(self, f):
        x1, x2, x3 = self[0,:]
        y1, y2, y3 = self[1,:]
        A = array([[x2 - x1, x3 - x1],
                   [y2 - y1, y3 - y1]])
        J = det(A)
    def f_(xi, eta):
        x = x1 + (x2 - x1)*xi + (x3 - x1)*eta
        y = y1 + (y2 - y1)*xi + (y3 - y1)*eta
        return f(x, y)
    return (1/6)(f_(0, 0) + f_(0, 1) + f_(1, 0))

def f(x, y):
    return x**2/10 - y**2/10 + 1

el = array([[3, 11, 0],
            [0, 4, 6]])
EL = elem(el)
print(EL.Jac(f))

当我运行这段代码时,有一个 TypeError: 'elem' object is not subscriptable。如果我替换

x1, x2, x3 = self[0,:]

x1, x2, x3 = self.coords[0,:]

它会引发 AttributeError: 'elem' object has no attribute 'coords'。

谁能帮我解决这个问题?

标签: pythonclassmethods

解决方案


__getitem__

为了使对象成为可子对象,您需要在类中实现getitem ( https://docs.python.org/3/reference/datamodel.html#object.getitem )

但是,您需要将值分配给对象,例如

class Some:

    def __init__(self, v):
        self.v = v

    def __getitem__(self, i):
        return self.v[i]


some = Some([1,2,3])
print(some[:2])

结果是

[1, 2]

这也应该适用于 numpy,我假设你使用它。

collections.UserList

基本上,您想要的是扩展列表功能。您可以使用内置集合模块中的 UserList 类:https ://docs.python.org/3/library/collections.html#collections.UserList

但是,据我所知,这不适用于 numpy 数组。

numpy.ndarray

在 numpy 中,您可以从 ndarray 类继承,例如:

from numpy import ndarray


class A(ndarray):    
    def custom_function(self, x):
        return self + x

a = A([1,2,3])
print(a.custom_function(666))

结果是

A([[[666., 666., 666.],
    [666., 666., 666.]]])

链接:

https://docs.scipy.org/doc/numpy/user/basics.subclassing.html#basics-subclassing https://docs.scipy.org/doc/numpy/reference/arrays.classes.html https:// docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray

这两个示例都是可下标的。

我希望这有帮助。

多一点

您的代码将不起作用,因为您在类主体中有一个 return 语句,而不是一个函数。

请不要忘记在问题中说明导入语句。数组不是 python 标准库的一部分。我只是猜测它是 numpy,因为 shape 属性。


推荐阅读