首页 > 解决方案 > “dict”对象没有属性“y”。我对这意味着什么以及如何解决感到困惑

问题描述

我正在使用 odeint 来求解一个由 6 个方程组成的系统。然后我想将我的解决方案保存到变量 x6a, y6a, z6a, x6b, y6b, z6b 中:

x6_a, y6_a, z6_a, x6_b, y6_b, z6_b = sol6.y

但由于错误,我的代码此时开始失败:

'dict' object has no attribute 'y'

这是我的代码的最小可重现示例:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def coupled_jac(X, t, sigma, r, b, C1, C1x, S, O, C2, C2x, tau):
    jac = np.array([[-sigma, sigma, 0, -C1*X[3], 0, 0], [r+X[2], -1, -X[0], 0, C1*S, 0], [X[1], X[0], -b, 0, 0, C1x*S], [-tau*C2, 0, 0, -tau*sigma, tau*sigma, 0], [0, tau*C2, 0, tau*r-S*X[5], -r*tau, -tau*S*X[3]], [0, 0, tau*C2x, tau*S*X[4], tau*S*X[3], -b*tau]])
    return jac

def lorenz_coupled(X, t, sigma, r, b, C1, C1x, S, O, C2, C2x, tau):
    rhs = [sigma * (X[1] - X[0]) - C1 * (S*X[3] - O), r*X[0] - X[1] - X[0]*X[2] + C1 * (S*X[4] - O), X[0]*X[1] - b*X[2] + C1x*S*X[5], (sigma * (X[4] - X[3]) - C2 * (X[0] + O)) * tau, (r*X[3] - X[4] - S*X[3]*X[5] + C2 * (X[1] + O)) * tau, (S*X[3]*X[5] - b*X[5] + C2x*X[2]) * tau]
    return rhs

#Initial conditions
X0 = np.array([1, 1, 1, 1, 1, 1])

#maiximum time
t_max = 50
t = np.linspace(0, t_max, 1000*t_max + 1)

#parameters
sigma = 10
r = 28
b = 8/3
tau = 0.1
S = 0.5
C1 = 1
C2 = 1
C1x = 1
C2x = 1
O = -11

#solve function
X, sol6 = odeint(lorenz_coupled, X0, t, args=(sigma, r, b, C1, C1x, S, O, C2, C2x, tau), Dfun=coupled_jac, full_output=True)

x6_a, y6_a, z6_a, x6_b, y6_b, z6_b = sol6.y

# time 
t = np.linspace(0, t_max, 10*t_max + 1)
fig = plt.figure(figsize=(16, 8)) #specify the size of plot
ax = fig.add_subplot(1, 2, 1, projection='3d')

#plot the fast equations
ax.plot(x6_a, y6_a, z6_a)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.title("The Fast Coupled Lorenz Attractor")

#plot the slow coupled equations
ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot(x6_b, y6_b, z6_b)

#title and axis label
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.title("The Slow Coupled Lorenz Attractor")

标签: pythonplot

解决方案


注释 0

有些错误比其他错误更难理解。

我要稍微“宝贝”你一下,因为大多数程序员都会理解你的错误信息 ( dict has no attribute named 'y')

如果以下讨论看起来“太容易”或过于简单,请原谅我。

注1

以下代码将产生与您的代码相同的错误:

sol6 = dict()    
z = sol6.y     

您收到的错误消息是:

'dict' object has no attribute 'y'

如果您消除所有无关代码,就更容易判断您在编程中犯了什么错误。

每当 python 脚本不工作时,一个非常有用的方法是:

  1. 保存代码的备份副本。
  2. 将您的 python 脚本复制并粘贴到一个新文件中
  3. 删除一小段代码
  4. 重新运行脚本
  5. 根据错误信息的变化采取行动
    :如果错误消失: * 将删除的代码放回去。 * 然后,转到步骤 3(删除代码)
    b。如果显示相同的错误消息,请继续删除代码(转到步骤 3)。

目标是“削减”所有代码,直到只剩下错误。

如果您的脚本长达数百行,则很难找到错误。

尝试创建尽可能少的 python 代码来重现相同的错误消息。

笔记2

对于习惯于使用“”的程序员来说,为什么会出现错误是非常明显的。

字典类没有成员变量或方法,名为“ y

您在 C++、Java 或任何其他语言中都会遇到几乎相同的错误,而不仅仅是 Python。

一个“”代表一个复杂的事物,比如一个人。类
的“成员变量”记录了关于更复杂的“
的简短事实Person

课堂就像一张记录小事实的填空表。
例如,一个JobApplicant类可能有:

  • 求职者的名字
  • 申请人的姓氏
  • 申请人的年龄
  • 申请人的电话号码
  • 求职者的电子邮件地址。
  • ETC...

假设有人正在为人们买卖房屋的网站编写代码。您可以编写一个名为的类House,用于存储有关待售房屋的统计信息:

class House:
    * number of bedrooms 
    * number of bathrooms
    * square footage of the house    
    * asking price to buy the house     
    * mailing address/location of the house
    * etc...      

一个类的成员变量通常是事物(而不是动作),例如:

  • 大量的
  • 速度
  • 颜色
  • 温度

类“方法”是用于操作成员变量的函数。网络是动作,例如:

  • 更改名字
  • 更改电话号码
  • 删除
  • 插入
  • 旋转
  • 反映
  • 翻译
  • 放大
  • 收缩

什么是“类实例”或“对象”?

下面是一些词汇:

  • 类的实例
  • 类对象
  • 目的

上述所有术语的含义相同。

一个类的实例 就像一个工作申请,将所有的信息都填上。
工作申请的实例/对象可能会说“名字”,也可能会说“莎拉”

班级

班级就像一张尚未填写的纸质工作申请表。
一个说“名字”并且有一个空行。
一个通常不会指定一个人的名字实际上是什么(Robby、John、Sarah、Ian、Fred 等......)

类的伪代码:

以下是“伪代码”。
伪代码比 python 更容易阅读。
如果英语处于光谱的一端,而 python 是光谱的另一端,那么“伪代码”就在光谱的中间。

begin class named `Rectangle`:

    begin member variables:

        integer my_length;
        integer my_width;

    end of member variables.

    begin methods:

        def get_area():
            return my_length * my_width;

    end of methods.   
end of class named 'Rectangle'   

考虑以下伪代码:

Robby = Rectangle(4, 8);
w = Robby.my_width;

我将上面的代码翻译成英文:

  1. 构造一个具有width = 4和的新矩形length = 8
  2. 将新的 Rectangle 存储在名为Robby
  3. 从中获取my_width变量Robby
  4. my_width变量从Robby

请注意,代码如下:

Robby.my_width
Robby.get_width()

在英语中的意思是“得到罗比的宽度”。

类似的东西x = Robby.favorite_ice_cream_flavor没有意义,因为矩形没有最喜欢的冰淇淋味道。

回想一下,这Robby是一个矩形。

你的代码是这样的:

this_dict = {
    "brand": "Ford",
    "model": "Mustang",
    "year": 1964
 }
 blah = this_dict.y

字典,例如this_dict没有命名的成员变量y

字典就像输入和输出的表:

+-------+---------+
| INPUT | OUTPUT  |
+-------+---------+
| A     | APPLE   |
| B     | BANANA  |
| C     | CHARLIE |
+-------+---------+

+-------+--------+
| INPUT | OUTPUT |
+-------+--------+
| x     |   54.1 |
| y     |   15.3 |
| z     |   99.3 |
+-------+--------+

字典本质上是一个“查找表”。
您在输入列中搜索特定输入。
然后您按照该行查看输出是什么。

python“字典”很像数学中的有限函数。
有输入,有输出。

Python 字典非常有限。尽量保持元素的数量少于10,000
偶数10,000会稍微推动边界。

计算机编程“函数”既不像数学课上的函数,也不像字典。

计算机编程“功能”就像一本食谱。
计算机编程“函数”解释了如何烤蛋糕。
计算机编程“功能”不是很有限(可能有无限多的输入)

无论如何,python 字典没有一个名为的属性y,原因与矩形没有一个名为favorite flavor of ice-cream. 这没有任何意义。

“字典”和“数组”之间的主要区别在于:

  • 数组的输入总是整数 1, 2, 3, .... n
  • 字典的输入可能是整数,但也可能是其他内容,例如英文单词:“red”、“blue”、“orange”。

以下是如何创建字典以及之后如何使用它的示例:

student_grades = {
    "Joe McCormic": 95.7
    "Lance Armstrong": 87.4,
    "Sarah McPherson": 99.83
    "Kenneth Moer": 77.1
 }
 
def number_to_letter(number: float):
    number = float(number)
    if number > 90:
        return "-A"
    return "F"

    # if number <= 90
    #     return "F"

Joe_McCormic_number = student_grades["Joe McCormic"]

print("Joe_McCormic_number = ", Joe_McCormic_number)

Joe_McCormic_letter_grade = number_to_letter(Joe_McCormic_number)

无论如何,字典没有名为y.

属性始终位于点 ( .) 的右侧:

    object.attribute

    my_house.number_of_bedrooms

    Sarah.first_name

    Sarah.phone_number

    my_car.year_of_manufacter

以下是字典确实具有的一些属性的列表:
y不是有效的字典属性。

  • clear() 删除/清除字典中的所有元素。

    car_dict = {               #
        "brand": "Ford",       #
        "model": "Mustang",    #
        "year": 1964           #
    }                          #
                               #
    print(len(car_dict))       # prints '3'
    car_dict.clear()           # deletes everything from the dictionary
    print(len(car_dict))       # prints '0'
    
  • __len__()len ”代表“长度”。该__len__()方法输出字典的长度。换句话说,它将允许输入的数量输出到字典。

    car_dict = {               #
        "brand": "Ford",       #
        "model": "Mustang",    #
        "year": 1964           #
    }                          #
                               #
    print(len(car_dict))       # prints '3'
    print(car_dict.__len__())  # equivalent to the above
    
  • copy()返回字典的副本。

    new_dict = old_dict.copy()
    
  • fromkeys() 返回具有指定键和值的字典
  • get()返回指定键的值
  • items() 返回包含每个键值对的元组的列表
  • keys() 返回包含字典键的列表
  • pop()删除具有指定键的元素
  • popitem()删除最后插入的键值对
  • setdefault() 返回指定键的值。如果key不存在:插入key,指定值
  • update() 使用指定的键值对更新字典
  • values() 返回字典中所有值的列表

以下代码片段中的底部两行是等效的:

d = dict()
d["ham"] = 83

# The following two lines are equivalent:   
x = d["ham"]
x = d.__getitem__("ham") 

我只是想表明涉及字典的所有内容都涉及访问字典的属性。甚至 []运算符实际上也只是__getitem__属性。

没有名为的字典的属性y

d = dict()
temp_var = d.y  

错误

AttributeError: 'dict' object has no attribute 'y'

推荐阅读