Python模块 - 范围 [英] Python modules - Scopes

查看:102
本文介绍了Python模块 - 范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现我认为python 3.4的独特行为。为了说明这个问题,我现在有一个python程序(模块),peculiar.py,包含一个Python程序类和一些功能。其中一个功能是实例化类Point中的点。
当我离开pygame窗口时,一个点通过这个函数add_point从类Point实例化。在命令窗口中列出了以这种方式创建的实例。这一切都可以。正如我们所看到的那样,积分点被添加到points_list并列在命令窗口中。



右键单击窗口使得函数调用相同的函数(add_point)在另一个模块(pec_controls.py)中。
然后实例化一个点,但它似乎被添加到一个新的或不同的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 
#通过python 3.4或python来显示特殊行为的示例?
#左击窗口单独通过此模块实例化点(请参阅命令窗口)。
#右击窗口实例化来自pec_controls.py模块的点。
#右键单击,而不是直接调用add_point函数,如左键单击,调用pec_controls.py中的函数,然后调用此模块中的add_point函数。
#特别的是,这导致Class Point似乎创建了全局列表points_list的新列表,
#仅包含从pec_controls模块实例化的项目(即通过右击窗口)ref。命令窗口。
#再次左键单击,使该类返回到原始列表,像往常一样添加左点击点实例。
#显然现在有两个不同的列表?这是一个错误还是打算?

从pygame.locals导入pygame,sys,pec_controls
导入*

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说:,len(points_list),points)

def update(self):
self.rect.x = self.position [0]
self.rect.y = self.position [1]
pass
$ b def add_point(x = None,y = None):
display_frame()
point = Point()
为i在points_list中:#通过从controls.py通过btn_add_point_clicked_left调用类创建的点。
print(add_point says,i,i.position)#ref:显示通过从主
print(add_point,points_list)调用类所产生的点的框架# points_list !!!!!!!!


def process_events():
用于pygame.event.get()中的事件:
if event.type == pygame.QUIT:
返回True
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
add_point()#通过btn_add_point_clicked实例化一个点。 (Ok / Normal)
print(Left Click)
elif event.button == 3:
pec_controls.clicked_right()#通过pec_controls模块通过add_point实例化一个点。 (特殊结果!!!!)
print(右键单击)
通过
返回False

def display_frame():
for i in points_list:#在全局列表中写出点数points_list
print(display says,i,i.position)#
print(display,points_list)#

main main():#主要函数
pygame.init()
main.screen = pygame.display.set_mode((200,200),0,32)
main.clock = pygame。 time.Clock()

point = Point()#从该模块的main实例化一个点
point.position =(100,200)

add_point()#通过函数add_point

main.done = False
从主函数形式化点而不是main.done:
main.done = process_events()
main.clock.tick(FPS)
#display_frame()

pygame.quit()

if __name__ ==__main__:
main()


你遇到的问题是当 peculiar.py 作为脚本运行时,它不被认为是特有模块。它被认为是 __ main __ 模块。导入 peculiar 将再次运行该文件,生成 Point 类的另一个副本, points_list list,等等。



我建议将程序的 main 功能分离一个单独的文件,用于导入 peculiar 并调用特有的模块中的所有内容。或者,您可以使用 import unique;如果__name__ ==__main __块,中的peculiar.main()


I found what I think is peculiar behaviour by python 3.4. I made these small files to illustrate the problem I am facing.

To focus on the problem, I now have a python program(module), peculiar.py, containing a class, and some functions. One of the functions are instantiating points from the class Point. When I left click the pygame window, a point is instantiated from the class Point, by this function, add_point. In the command window the instances created this way is listed. Everything is ok with this. As we can see the points crated are added to the points_list and listed in the command window.

Right clicking the window makes the very same function (add_point) called by a function in another module (pec_controls.py). A point is then instantiated, but it seems to be added to a new or different points_list, adding only points instantiated by right clicking the window. If we toggle between right and left clicking the window, the class toggles between two different versions of the points_list.

I could understand this behavior if the class was called directly from pec_controls.py, i.e. the point was instantiated in pec_control.py, but not as now, when it is the very same function in peculiar.py that calls the class in all instances. I am kind of "passing the scope" to pec_control module when I right click, but I think one should expect the scope to be returned, when that module then calls add_point, back in peculiar.py. It is very unexpected to put it mildly that where you call a function from is significant to it's, and or, a class's behavior.

Could someone explain the rationale behind this behavior by python? Is there something I forgot, to make all the instances appear in the same list?

Here is pec_controls.py:

import peculiar, sys, pygame

def clicked_right():
    peculiar.add_point()

and here is 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()

解决方案

The problem you're running into is that when peculiar.py is run as a script, it is not considered to be the peculiar module. It is considered to be the __main__ module. Importing peculiar will run the file again, producing a separate copy of the Point class, the points_list list, and so on.

I recommend separating your program's main functionality into a separate file that imports peculiar and calls the versions of everything from the peculiar module. Alternatively, you can use import peculiar; peculiar.main() in your if __name__ == "__main__" block.

这篇关于Python模块 - 范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆