jupyter 笔记本中 python 的奇怪行为;这是一个错误还是我应该接受它?
Weird behaviour with python in jupyter notebook; is this a bug or should I just accept it as it is?
当我偶然发现一些奇怪的行为时,我正在修补 jupyter notbook 中的一个小项目想法......
以下代码摘自原文
class MyClass:
Instances = []
def __init__(self,name=None):
self.id = len(MyClass.Instances)
MyClass.Instances.append(self)
if name is None:
self.name = 'Class %s' % self.id
else:
self.name = name
def show(self):
print('Name: %s\nId: %s' % (self.name, self.id))
def instance_at(i : int):
if i >= len(MyClass.Instances):
raise ValueError("Instance does not exist")
return MyClass.Instances[i]
(我希望代码是不言自明的)
我 运行 单元格并测试了代码,它工作正常:
In [24] : m = MyClass()
m.show()
Out [25] : Name: Class 0
Id: 0
扭曲:
我不喜欢第一个实例,没有给出名字,会被称为 'Class 0' 所以我心想:'Why not add an object which will act as a placeholder for the index 0'(不要问我为什么这样做,'真是个脑残)。
所以我将第 2 行更改为 Instances = [MyClass(name='id')
。这也有效,但是当我尝试在索引 0 处接收实例时,它的 id 值与我预期的不同。
In [24] : m = MyClass()
m.show()
MyClass.instance_at(0).show()
Out [25] : Name: Class 0
Id: 1
Name: id
Id: 1
这就是我决定在另一个笔记本中编写我的代码的更通用版本(此处显示的代码)的原因。我在 运行 单元格之前完整地写了它,包括 Instances = [MyClass(name='id')]
.
这次我得到了这个:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-60020e1975a4> in <module>
----> 1 class MyClass:
2 Instances = [MyClass(name='id')]
3 #Instances = []
4
5 def instance_at(i : int):
<ipython-input-1-60020e1975a4> in MyClass()
1 class MyClass:
----> 2 Instances = [MyClass(name='id')]
3 #Instances = []
4
5 def instance_at(i : int):
NameError: name 'MyClass' is not defined
所以现在我有一段代码可以在一个笔记本上运行,但不能在另一个笔记本上运行。至少当你简单地复制和粘贴它时。在 jupyter notebook 中,这可以通过将第 2 行更改为 Instances = []
、运行 单元格并将其改回来解决。
我相当确定这是因为 class 和 class 变量 Instances
在我创建不明确的代码行之前已经存在。
事后看来,这确实有道理,我怀疑意外的 id 值来自创建实例 m
时在列表中发现的构造函数调用。
我错了吗?谁能详细说说?
如果这样的post在这里不合适,请告诉我。
一个更简单的例子:
class Example:
def __init__(self):
print("Creating an instance of the OLD class")
class Example: # redefining like this does **not** cause an error
Instances = [Example()]
def __init__(self):
print("Creating an instance of the NEW class")
# the OLD message is printed immediately
# because `Instances = [Example()]` uses the previous definition
# because it **cannot** use the current one; it hasn't been created yet.
# You **do** get an error **without** the old definition, because then
# there isn't a definition at all.
x = Example() # the NEW message is printed
# the OLD class **still exists**, but cannot easily be accessed.
# As long as we can think of a way to get at an instance,
# we can use the `__class__` of the instance to create more;
# and we can rename that to make it easily usable:
Old_Example = Example.Instances[0].__class__
y = Old_Example()
当我偶然发现一些奇怪的行为时,我正在修补 jupyter notbook 中的一个小项目想法...... 以下代码摘自原文
class MyClass:
Instances = []
def __init__(self,name=None):
self.id = len(MyClass.Instances)
MyClass.Instances.append(self)
if name is None:
self.name = 'Class %s' % self.id
else:
self.name = name
def show(self):
print('Name: %s\nId: %s' % (self.name, self.id))
def instance_at(i : int):
if i >= len(MyClass.Instances):
raise ValueError("Instance does not exist")
return MyClass.Instances[i]
(我希望代码是不言自明的)
我 运行 单元格并测试了代码,它工作正常:
In [24] : m = MyClass()
m.show()
Out [25] : Name: Class 0
Id: 0
扭曲:
我不喜欢第一个实例,没有给出名字,会被称为 'Class 0' 所以我心想:'Why not add an object which will act as a placeholder for the index 0'(不要问我为什么这样做,'真是个脑残)。
所以我将第 2 行更改为 Instances = [MyClass(name='id')
。这也有效,但是当我尝试在索引 0 处接收实例时,它的 id 值与我预期的不同。
In [24] : m = MyClass()
m.show()
MyClass.instance_at(0).show()
Out [25] : Name: Class 0
Id: 1
Name: id
Id: 1
这就是我决定在另一个笔记本中编写我的代码的更通用版本(此处显示的代码)的原因。我在 运行 单元格之前完整地写了它,包括 Instances = [MyClass(name='id')]
.
这次我得到了这个:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-60020e1975a4> in <module>
----> 1 class MyClass:
2 Instances = [MyClass(name='id')]
3 #Instances = []
4
5 def instance_at(i : int):
<ipython-input-1-60020e1975a4> in MyClass()
1 class MyClass:
----> 2 Instances = [MyClass(name='id')]
3 #Instances = []
4
5 def instance_at(i : int):
NameError: name 'MyClass' is not defined
所以现在我有一段代码可以在一个笔记本上运行,但不能在另一个笔记本上运行。至少当你简单地复制和粘贴它时。在 jupyter notebook 中,这可以通过将第 2 行更改为 Instances = []
、运行 单元格并将其改回来解决。
我相当确定这是因为 class 和 class 变量 Instances
在我创建不明确的代码行之前已经存在。
事后看来,这确实有道理,我怀疑意外的 id 值来自创建实例 m
时在列表中发现的构造函数调用。
我错了吗?谁能详细说说?
如果这样的post在这里不合适,请告诉我。
一个更简单的例子:
class Example:
def __init__(self):
print("Creating an instance of the OLD class")
class Example: # redefining like this does **not** cause an error
Instances = [Example()]
def __init__(self):
print("Creating an instance of the NEW class")
# the OLD message is printed immediately
# because `Instances = [Example()]` uses the previous definition
# because it **cannot** use the current one; it hasn't been created yet.
# You **do** get an error **without** the old definition, because then
# there isn't a definition at all.
x = Example() # the NEW message is printed
# the OLD class **still exists**, but cannot easily be accessed.
# As long as we can think of a way to get at an instance,
# we can use the `__class__` of the instance to create more;
# and we can rename that to make it easily usable:
Old_Example = Example.Instances[0].__class__
y = Old_Example()