在Python中如何从被调用模块访问调用模块名称空间?
我为SQLite制作了一个小小的sql渲染器/包装器。主要思想是写:在Python中如何从被调用模块访问调用模块名称空间?,python,sqlite,namespaces,eval,Python,Sqlite,Namespaces,Eval,我为SQLite制作了一个小小的sql渲染器/包装器。主要思想是写: execute( 'select * from talbe1 where col1={param1} and col2={param2}' ) 而不是 execute( 'select * from table1 where col1=? and col2=?', (param1,param2) ) 代码如下: import re import sqlite3 class SQLWrapper(): def __
execute( 'select * from talbe1 where col1={param1} and col2={param2}' )
而不是
execute( 'select * from table1 where col1=? and col2=?', (param1,param2) )
代码如下:
import re
import sqlite3
class SQLWrapper():
def __init__(self, cursor):
self.cursor = cursor
def execute(self, sql):
regexp=re.compile(r'\{(.+?)\}')
sqlline = regexp.sub('?',sql)
statements = regexp.findall(sql)
varlist = tuple([ eval(_statement) for _statement in statements ])
self.cursor.execute(sqlline, varlist)
return self
def fetchall(self):
return self.cursor.fetchall()
#usage example
db = sqlite3.connect(':memory:')
cursor = db.cursor()
wrap = SQLWrapper(cursor)
wrap.execute('create table t1(a,b)')
for i in range(10):
wrap.execute('insert into t1(a,b) values({i}, {i*2})')
limit = 50
for line in wrap.execute('select * from t1 where b < {limit}').fetchall():
print line
即,变量I在其他模块中不可见。如何克服这个问题?这违反了大多数编程语言的正常范围规则 通常,您不希望您调用的函数(或方法)以某种方式神奇地使用您自己的变量进行操作。这意味着,只有那些变量值(!)才可访问被调用的例程,您将其显式添加为参数 当您在第一个代码中(全部在一个模块中)将带有i的for循环移动到自己的函数中时,将遇到相同的问题——我将是该函数的本地对象,并且对SQLwrapper不可见 范围规则有意地将变量的访问限制为“范围内”的变量,而不允许访问“范围外”的变量。因此,进行了一些信息隐藏,降低了复杂性 这意味着在某些情况下会有一些编写开销,但也会抑制一些危险的做法和复杂性,从而使程序更加节省 当您只打算使用SQLite(或MySQL)时,我会推荐类似的方法: 因此,您有了一个更可读、更容易理解的版本,但没有遇到的范围问题。@-前缀可以在SQLite上使用,据我所知,它也可以在MySQL中使用——但它是特定于数据库的(遗憾的是,SQL没有将其标准化)。在sqlite3模块的文档中,使用了另一个前缀“:”这也适用于SQLite,但我不知道在哪个数据库上 见: 顺便说一句,如果您想减少一点书写开销,您可以编写如下包装器:
def myExcecute(sql, **params):
self.cursor.execute(sql, params)
因此,您可以用更少的开销(和更少的括号)调用execute:
execute( 'select * from table1 where col1=@param1 and col2=@param2', {'param1': param1, 'param2': param2} )
def myExcecute(sql, **params):
self.cursor.execute(sql, params)
myExecute( 'select * from table1 where col1=@param1 and col2=@param2', param1=param1, param2=param2 )