“语法警告:名称 'our_mongo' 在全局声明之前使用”

Posted

技术标签:

【中文标题】“语法警告:名称 \'our_mongo\' 在全局声明之前使用”【英文标题】:"SyntaxWarning: name 'our_mongo' is used prior to global declaration"“语法警告:名称 'our_mongo' 在全局声明之前使用” 【发布时间】:2016-04-23 02:37:54 【问题描述】:

我的代码不断给我上述语法警告。我的代码包括但不限于:

class SocketHandler(WebSocketHandler):
    def on_message(self, message):
        ball = json.loads(message)
        user = User(ball['identifier'])
        if ball['command'] == 'search':
            global our_mongo
            search_results = our_mongo.find('$text':'$search':ball['search_term'],'score':'$meta':"textScore")
            self.write_message(
                    'command': 'search-results',
                    'results': list(search_results.sort([('score', '$meta': 'textScore')]).limit(10)),
            )
        elif ball['command'] == 'save-node': # hopefully this can handle both new nodes and changes to nodes
            node_dict = ball['node_dict']
            if 'importance' in node_dict.keys():
                node_dict['importance'] = int(node_dict['importance'])
            try:
                node_obj = node.create_appropriate_node(node_dict)
                print('node made.  looks like: '+str(node_obj)+'.  Now time to put it into the DB...')
                global our_mongo
                # take a look at the dependencies now
                previous_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find("_id": node_obj.id))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
                print('prev deps are: '+str(previous_dependency_ids))
                our_mongo.upsert( "_id": node_obj.id , node_obj.__dict__)
                # take a look at the current dependencies
                current_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find("_id": node_obj.id))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
                print('curr deps are: '+str(current_dependency_ids))
                update_our_DAG()
                # send an update of the graph to the user if there is a new dependency:
                for new_dependency in set(current_dependency_ids) - set(previous_dependency_ids):
                    self.request_node(new_dependency, ball, user)
                # OR IF THE SAVED NODE IS A BRAND NEW NODE, we have to include all the deps
            except Exception as error:
                # stuff didn't work, send error back to user
                print('ERROR: '+str(error))
                self.write_message(
                    'command': 'display-error',
                    'message': str(error),
                )


def update_our_DAG():
    # 1. grab nodes and edges from database
    all_node_dicts = list(Mongo("math", "nodes").find())

    # 2. create a networkx graph with the info...
    global our_DAG
    our_DAG = nx.DAG()
    for node_dict in all_node_dicts:
        node = create_appropriate_node(strip_underscores(node_dict))
        our_DAG.add_n(node)

def make_app():
    return Application(
        [
            url('/', RedirectHandler, "url": "index.html", name="rooth"),
            url('/websocket', SocketHandler),
            url('/json', JSONHandler, name="jsonh"),
            url(r'/index(?:\.html)?', IndexHandler, name="indexh"),
            # captures anything at all, and serves it as a static file. simple!
            url(r'/(.*)', StaticHandler, "path": "../www/"),
        ],
        # settings:
        debug=True,
    )

def make_app_and_start_listening():
    # enable_pretty_logging()
    application = make_app()
    # by listening on the http port (default for all browsers that i know of),
    # user will not have to type "http://" or ":80" in the URL
    application.listen(80)
    # other stuff
    IOLoop.current().start()


if __name__ == "__main__":
    # 0. create a global mongo object for later use (for upserts in the future)
    our_mongo = Mongo("math", "nodes")

    # 1 and 2
    update_our_DAG()

    axioms = [our_DAG.n(node_id) for node_id in ['set', 'multiset', 'vertex']]

    # 3. launch!
    make_app_and_start_listening()

我已经尝试了所有方法,但仍然存在问题。为什么这是语法错误?解决此问题的最佳方法是什么?

【问题讨论】:

您没有在显示的代码中的任何地方使用our_mongo 我现在已经包含了更多相关的代码。 SocketHandler 在哪里使用? 我认为这与问题无关,但我已经包含了使用SocketHandler 的代码。现在它包括our_mongo 的所有外观。因此,就范围界定而言,所有需要的信息都已存在。 对不起。我误解了这个问题。尝试在文件顶部执行our_mongo = None 【参考方案1】:

不是SyntaxError,而是SyntaxWarning。 Python 警告您在函数中使用our_mongo 变量beforeglobal our_mongo。 从语法上讲,global 语句在函数的哪一行实际上并不重要;但惯用的方法是在第一次访问之前使用global

另外一个问题是你有多个global our_mongo 语句,而单个语句可以,而且你甚至根本不需要global - 它仅适用于when you want to assign a new value to the global variable 的情况;即

def foo():
    global bar        # this line is required for the next line 
                      # to change the global variable instead of
                      # the local variable
    bar = 42

因此,只需从您的 on_message 中完全删除所有 global 语句,它们是不必要的。

【讨论】:

我是否可以阅读一些资源来解释何时需要global 语句以及何时它们是可选的?或者,也许您声明只有当您为全局变量分配一个新值时才需要它是关于此事的最后声明?感谢您的帮助。【参考方案2】:

在函数中声明名称global 的唯一原因是它将绑定在全局范围而不是本地范围内;当 访问 一个名称时,始终会搜索全局范围。由于您的代码从未在任何函数中绑定our_mongo,因此没有理由首先声明它global

【讨论】:

以上是关于“语法警告:名称 'our_mongo' 在全局声明之前使用”的主要内容,如果未能解决你的问题,请参考以下文章