我发现我认为python 3.4的特殊行为。我制作了这些小文件来说明我面临的问题。
为了关注这个问题,我现在有一个python程序(模块),peculiar.py,包含一个类和一些函数。其中一个函数是从Point类实例化点。 当我左键单击pygame窗口时,通过此函数add_point从类Point实例化一个点。在命令窗口中,列出了以这种方式创建的实例。一切都很好。正如我们所看到的那样,crated点被添加到points_list并在命令窗口中列出。
右键单击窗口会使另一个模块(pec_controls.py)中的函数调用的函数(add_point)完全相同。 然后实例化一个点,但它似乎被添加到一个新的或不同的points_list,只添加通过右键单击窗口实例化的点。如果我们在左右单击窗口之间切换,则该类会在points_list的两个不同版本之间切换。
如果直接从pec_controls.py调用该类,我可以理解这种行为,即该点在pec_control.py中实例化,但不是现在,当它是peculiar.py中调用该类的相同函数时所有实例。 当我右键单击时,我有点“将范围”传递给pec_control模块,但我认为当该模块然后调用add_point返回peculiar.py时,应该期望返回范围。 温和地说,你调用函数的地方对于它来说是非常重要的,或者是一个类的行为。
有人可以通过python解释这种行为背后的基本原理吗? 有没有我忘了,让所有实例出现在同一个列表中?
这是pec_controls.py:
import peculiar, sys, pygame
def clicked_right():
peculiar.add_point()
这里是peculiar.py:
# peculiar.py
# Sample to show peculiar behaviour by python 3.4, or python in general?
# Left clicking window instantiates point by this module alone(see command window).
# Right clicking window instantiates point from pec_controls.py module.
# Right clicking, instead of calling add_point function directly, as left clicking does, calls function in pec_controls.py, which then calls the add_point function in this module.
# What is peculiar is that this is resulting in Class Point seeming to make a new list of the global list points_list,
# only containing the items instantiated from pec_controls module(i.e. by right clicking window) ref. command window .
# Left clicking again, makes the Class go back to the original list, adding "leftclicked" point instances as usual.
# Apparently there is now two different lists? Is this a bug or intended?
import pygame, sys, pec_controls
from pygame.locals import *
FPS = 10
points_list = []
class Point():
def __init__(self):
points_list.append(self)
self.position = (10 * len(points_list), 10 * len(points_list))
print("Class says: ",len(points_list), "points")
def update(self):
self.rect.x = self.position[0]
self.rect.y = self.position[1]
pass
def add_point( x = None, y = None):
display_frame()
point = Point()
for i in points_list: # The points created by calling the class from controls.py via btn_add_point_clicked_left.
print ("add_point says", i, i.position) # ref: Display frame which prints out the points made by calling the class from main
print ("add_point", points_list) # This writes out points in points_list !!!!!!!!
def process_events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
return True
if event.type == pygame.MOUSEBUTTONUP :
if event.button == 1:
add_point() # Instantiates a point via btn_add_point_clicked. (Ok/Normal)
print("Left Click")
elif event.button == 3:
pec_controls.clicked_right() # Instantiates a point via pec_controls module via add_point. (Peculiar result !!!!)
print("Right Click")
pass
return False
def display_frame():
for i in points_list: # Writes out the points in the global list points_list
print ("display says", i, i.position) #
print("display", points_list) #
def main(): # Main function
pygame.init()
main.screen = pygame.display.set_mode((200,200),0,32)
main.clock = pygame.time.Clock()
point = Point() # Instantiates a point from main of this module
point.position =(100,200)
add_point() # Instatiates a point from main via the function add_point
main.done = False
while not main.done:
main.done = process_events()
main.clock.tick(FPS)
#display_frame()
pygame.quit()
if __name__ == "__main__":
main()
答案 0 :(得分:1)
您遇到的问题是,当peculiar.py
作为脚本运行时,它不会被视为peculiar
模块。它被认为是__main__
模块。导入peculiar
将再次运行该文件,生成Point
类,points_list
列表的单独副本,等等。
我建议将程序的main
功能分离到单独的文件中,该文件导入peculiar
并从peculiar
模块调用所有版本。或者,您可以在import peculiar; peculiar.main()
块中使用if __name__ == "__main__"
。