gpt4 book ai didi

python - Python 类字典有什么不同?

转载 作者:行者123 更新时间:2023-11-28 23:02:17 24 4
gpt4 key购买 nike

我在 Python 2.7 中遇到类属性问题,设法找到了解决方案,但我不明白。

在下面的设计代码中,我希望每首歌曲都有自己的字典,其中包含提到的星期几的歌词。

class Song:
name = ""
artist = ""
# If I comment this line and uncomment the one in the constructor, it works right
week = {}
def set_monday( self, lyric ):
self.week[ "Monday" ] = lyric;

.
. # silly, I know
.

def set_friday( self, lyric ):
self.week[ "Friday" ] = lyric;

def show_week( self ):
print self.week

def __init__(self, name, artist):
self.name = name
self.artist = artist

# Uncomment the line below to fix this
# self.week = {}

def main():
songs = {}

friday_im_in_love = Song( "Friday I'm in Love", "the Cure" )
friday_im_in_love.set_monday( "Monday you can fall apart" )
friday_im_in_love.set_tuesday( "Tuesday can break my heart" )
friday_im_in_love.set_wednesday( "Wednesday can break my heart" )
friday_im_in_love.set_thursday( "Thursday doesn't even start" )
friday_im_in_love.set_friday( "Friday I'm in love" )
songs[ "Friday I'm in Love" ] = friday_im_in_love

manic_monday = Song( "Manic Monday", "the Bangles" )
manic_monday.set_monday( "Just another manic Monday" )
songs[ "Manic Monday" ] = manic_monday

for song in songs:
# This shows the correct name and artist
print songs[song].name + " by " + songs[song].artist
# The dictionary is incorrect, though.
songs[song].show_week()

if __name__ == '__main__':
main()

除了上面代码运行时,输出是这样的:

Manic Monday by the Bangles
{'Friday': "Friday I'm in love", 'Tuesday': 'Tuesday can break my heart', 'Thursday': "Thursday doesn't even start", 'Wednesday': 'Wednesday can break my heart', 'Monday': 'Just another manic Monday'}
Friday I'm in Love by the Cure
{'Friday': "Friday I'm in love", 'Tuesday': 'Tuesday can break my heart', 'Thursday': "Thursday doesn't even start", 'Wednesday': 'Wednesday can break my heart', 'Monday': 'Just another manic Monday'}

这两个字典看起来都不像我期望的那样。所以回到代码,如果我在顶部注释 week = {},并在构造函数中取消注释 self.week={},字典就会按照我的方式出现期待。

Manic Monday by the Bangles
{'Monday': 'Just another manic Monday'}
Friday I'm in Love by the Cure
{'Friday': "Friday I'm in love", 'Tuesday': 'Tuesday can break my heart', 'Thursday': "Thursday doesn't even start", 'Wednesday': 'Wednesday can break my heart', 'Monday': 'Monday you can fall apart'}

这是为什么?

我意识到 name = ""artist = "" 行(可能)是不必要的,但由于它们确实有效,我必须问:由于 name 和 artist 字符串属性在构造函数之外似乎可以正常“初始化”;为什么没有周字典?

最佳答案

I realize the name = "" and artist = "" lines are (probably) unnecessary but since they do work, I must ask: Since the name and artist string properties appear to work fine "initialized" outside the constructor; why doesn't the week dictionary?

代码工作正是因为它们是不必要的。但是,不能“正常工作”,因为它们根本不能“工作”,因为它们是无关紧要的,因为它们是不必要的。

如果您在 __init__ 中设置了 week 字典,即使您将 week = {} 行留在类中,它也会起作用,因为相同的机制会启动.

让我们更仔细地看一下:

# If I comment this line and uncomment the one in the constructor, it works right
week = {}

Python 遵循一个非常简单的规则:在 class block 中编写的东西属于类,而不属于单个对象。要将某些内容附加到名为 self 的对象,您可以分配给它的一个 self.attributes。在这方面,__init__ 并不特殊;它可能会被自动调用并具有特定目的,但它与对象的交互方式与任何其他方法相同。 (因此即使在 __init__ 中也需要一个 self 参数。)

在您的 __init__ 中,您可以:

self.name = name
self.artist = artist

这会为类的每个对象附加一个属性(因为每个对象都会调用 __init__),隐藏类中的对象。当属性被查找时,它们会在类和对象中查找(如果在对象中找不到),但是当它们被赋值时,它们只是被分配给你说要分配给它的东西。 (要修改 Song 属性,您可以使用 Song.whatever = 42,即使在方法内部也是如此。)

当您在类中创建一个属性并且从未将属性分配给实例时,就会出现问题。请再次注意,__init__ 并不特殊;您可以稍后创建该类的新属性。

现在,由于 __init__ 并不特殊,假设我们在 __init__ 中执行其中一个示例函数的工作:

self.week["Friday"] = "gotta get down"

你看出区别了吗? week["Friday"] 不是属性名称; 是。所以我们不能像这样创建一个新属性。相反,我们正在修改现有对象,该对象被查找为self.week。哪个在类中找到一个,因为该对象没有一个。当我们再次查找 self.week 时,我们会看到变化,即使 self 是不同的 Song,因为只有一首Song.week.

如果我们用修改现有对象的东西替换 self.name = name,那么我们会看到相同的行为。然而,我们实际上不能那样做:self.name的初始值为'',它是一个字符串,而Python字符串无法就地修改它们。当您重新分配给一个包含字符串的变量时,您就是这样做的:重新分配。您使变量不再是旧对象的名称,而是开始成为新对象的名称。由于我们只能通过赋值影响 self.name,所以我们不能影响 Song.name,除非我们明确引用 Song.name

简单的解决方案是在__init__中设置属性:

self.week = {}

关于python - Python 类字典有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10082352/

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