我在Django工作。在Django中,当您呈现一个模板时,您会发送一个上下文字典来替换它。因为我很懒/很干燥,所以我经常使用局部变量()作为快捷方式,而不是发送一个类似于{'my_var':my_var,'var2':var2}的字典。
这通常是很好的工作,并节省了许多头脑麻木的重复。
我正在使用django--当某些事件发生时,通知发送电子邮件--比如您收到了一条私人消息。Django-通知附带了一个内置队列特性,我现在正在集成它。
然而,问题在于django通知在队列时对上下文字典进行了筛选。这就是局部变量()技巧失败的地方--本地字典除了局部变量(例如,它有、导入、和int())之外还有很多垃圾。当地人创造的字典不会泡菜。
我看到了三种选择: 1)重写django的排队方法--通知,以便在模板存储之前呈现它(简单,但有些乏味,并且破坏了可升级性);2)停止使用局部变量技巧,开始重复自己的操作;3)尝试找到一个更轻的本地版本(或者一种对本地进行腌制的方法)。
我在这里希望有人在3号方向有线索。
如果可能与此相关,下面是我试图使用局部变量()快捷方式进行筛选时所遇到的错误:
TypeError: can't pickle ellipsis objects此外,局部变量()的字典输出:
{
'__builtins__':
{
'bytearray': <type 'bytearray'>,
'IndexError': <type 'exceptions.IndexError'>,
'all': <built-in function all>,
'help': Type help() for interactive help,
or help(object) for help about object.,
'vars': <built-in function vars>,
'SyntaxError': <type 'exceptions.SyntaxError'>,
'unicode': <type 'unicode'>,
'UnicodeDecodeError': <type 'exceptions.UnicodeDecodeError'>,
'isinstance': <built-in function isinstance>,
'copyright': Copyright (c) 2001-2010 Python Software Foundation.
All Rights Reserved.
Copyright (c) 2000 BeOpen.com.
All Rights Reserved.
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.
Copyright (c) 1991-1995 Stichting Mathematisch Centrum,
Amsterdam.
All Rights Reserved.,
'NameError': <type 'exceptions.NameError'>,
'BytesWarning': <type 'exceptions.BytesWarning'>,
'dict': <type 'dict'>,
'input': <built-in function input>,
'oct': <built-in function oct>,
'bin': <built-in function bin>,
'SystemExit': <type 'exceptions.SystemExit'>,
'StandardError': <type 'exceptions.StandardError'>,
'format': <built-in function format>,
'repr': <built-in function repr>,
'sorted': <built-in function sorted>,
'False': False,
'RuntimeWarning': <type 'exceptions.RuntimeWarning'>,
'list': <type 'list'>,
'iter': <built-in function iter>,
'reload': <built-in function reload>,
'Warning': <type 'exceptions.Warning'>,
'__package__': None,
'round': <built-in function round>,
'dir': <built-in function dir>,
'cmp': <built-in function cmp>,
'set': <type 'set'>,
'bytes': <type 'str'>,
'reduce': <built-in function reduce>,
'intern': <built-in function intern>,
'issubclass': <built-in function issubclass>,
'Ellipsis': Ellipsis,
'EOFError': <type 'exceptions.EOFError'>,
'locals': <built-in function locals>,
'BufferError': <type 'exceptions.BufferError'>,
'slice': <type 'slice'>,
'FloatingPointError': <type 'exceptions.FloatingPointError'>,
'sum': <built-in function sum>,
'getattr': <built-in function getattr>,
'abs': <built-in function abs>,
'exit': Use exit() or Ctrl-D (i.e. EOF) to exit,
'print': <built-in function print>,
'True': True,
'FutureWarning': <type 'exceptions.FutureWarning'>,
'ImportWarning': <type 'exceptions.ImportWarning'>,
'None': None,
'hash': <built-in function hash>,
'ReferenceError': <type 'exceptions.ReferenceError'>,
'len': <built-in function len>,
'credits': Thanks to CWI,
CNRI,
BeOpen.com,
Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information.,
'frozenset': <type 'frozenset'>,
'__name__': '__builtin__',
'ord': <built-in function ord>,
'super': <type 'super'>,
'_': None,
'TypeError': <type 'exceptions.TypeError'>,
'license': Type license() to see the full license text,
'KeyboardInterrupt': <type 'exceptions.KeyboardInterrupt'>,
'UserWarning': <type 'exceptions.UserWarning'>,
'filter': <built-in function filter>,
'range': <built-in function range>,
'staticmethod': <type 'staticmethod'>,
'SystemError': <type 'exceptions.SystemError'>,
'BaseException': <type 'exceptions.BaseException'>,
'pow': <built-in function pow>,
'RuntimeError': <type 'exceptions.RuntimeError'>,
'float': <type 'float'>,
'MemoryError': <type 'exceptions.MemoryError'>,
'StopIteration': <type 'exceptions.StopIteration'>,
'globals': <built-in function globals>,
'divmod': <built-in function divmod>,
'enumerate': <type 'enumerate'>,
'apply': <built-in function apply>,
'LookupError': <type 'exceptions.LookupError'>,
'open': <built-in function open>,
'quit': Use quit() or Ctrl-D (i.e. EOF) to exit,
'basestring': <type 'basestring'>,
'UnicodeError': <type 'exceptions.UnicodeError'>,
'zip': <built-in function zip>,
'hex': <built-in function hex>,
'long': <type 'long'>,
'next': <built-in function next>,
'ImportError': <type 'exceptions.ImportError'>,
'chr': <built-in function chr>,
'xrange': <type 'xrange'>,
'type': <type 'type'>,
'__doc__': "Built-in functions,
exceptions,
and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.",
'Exception': <type 'exceptions.Exception'>,
'tuple': <type 'tuple'>,
'UnicodeTranslateError': <type 'exceptions.UnicodeTranslateError'>,
'reversed': <type 'reversed'>,
'UnicodeEncodeError': <type 'exceptions.UnicodeEncodeError'>,
'IOError': <type 'exceptions.IOError'>,
'hasattr': <built-in function hasattr>,
'delattr': <built-in function delattr>,
'setattr': <built-in function setattr>,
'raw_input': <built-in function raw_input>,
'SyntaxWarning': <type 'exceptions.SyntaxWarning'>,
'compile': <built-in function compile>,
'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'str': <type 'str'>,
'property': <type 'property'>,
'GeneratorExit': <type 'exceptions.GeneratorExit'>,
'int': <type 'int'>,
'__import__': <built-in function __import__>,
'KeyError': <type 'exceptions.KeyError'>,
'coerce': <built-in function coerce>,
'PendingDeprecationWarning': <type 'exceptions.PendingDeprecationWarning'>,
'file': <type 'file'>,
'EnvironmentError': <type 'exceptions.EnvironmentError'>,
'unichr': <built-in function unichr>,
'id': <built-in function id>,
'OSError': <type 'exceptions.OSError'>,
'DeprecationWarning': <type 'exceptions.DeprecationWarning'>,
'min': <built-in function min>,
'UnicodeWarning': <type 'exceptions.UnicodeWarning'>,
'execfile': <built-in function execfile>,
'any': <built-in function any>,
'complex': <type 'complex'>,
'bool': <type 'bool'>,
'ValueError': <type 'exceptions.ValueError'>,
'NotImplemented': NotImplemented,
'map': <built-in function map>,
'buffer': <type 'buffer'>,
'max': <built-in function max>,
'object': <type 'object'>,
'TabError': <type 'exceptions.TabError'>,
'callable': <built-in function callable>,
'ZeroDivisionError': <type 'exceptions.ZeroDivisionError'>,
'eval': <built-in function eval>,
'__debug__': True,
'IndentationError': <type 'exceptions.IndentationError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'classmethod': <type 'classmethod'>,
'UnboundLocalError': <type 'exceptions.UnboundLocalError'>,
'NotImplementedError': <type 'exceptions.NotImplementedError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
'OverflowError': <type 'exceptions.OverflowError'>
},
'notification': <module 'notification.models' from '/home/b/webapps/myapp/notification/models.pyc'>,
'u': <User: abcd>,
'User': <class 'django.contrib.auth.models.User'>
}发布于 2011-08-04 22:08:22
不是的。如果你要泡菜的话,那是值得重复的。许多对象,有些是不直观的,无法被腌制(即表单输入)。
只有当您确信模板将立即呈现时,才应使用局部变量()快捷方式。
发布于 2011-07-26 18:13:03
请允许我提出一种替代使用locals()的方法
class Object(object):
pass
def foo():
result = Object()
result.my_var = 'bar'
your_var = 'not to be returned'
result.var2 = 'baz' + result.my_var + len(your_var)
return result.__dict__另一种选择是在创建对象时将对象添加到上下文中。
def foo():
result = {}
result['my_var'] = my_var = 'bar'
your_var = 'not to be returned'
result['var2'] = var2 = 'baz' + my_var + len(your_var)
return result尽管如此,请确保每次修改变量(或至少是上次)时都会发生多个赋值。
编辑:您应该使用第二个版本的。我确信使用上下文dict (result或ctx或其他什么)的额外击键不会让人感到非常枯燥,但让我告诉您,这实际上是一件好事。Python声明的禅宗“显式优于隐式”。当您返回locals()的值时,您将返回谁知道是什么。全局命名空间中的所有内容,嵌套命名空间中的所有内容,您可能做过的每一个中间计算,所有这些都被隐式地返回给调用者。
如果您为您希望返回的值创建一个容器,则您将明确表示您的意图,在
this_is_for_me = 'foo'和
result['this_is_for_you'] = 'bar'在代码中可以清楚地看出,什么是公共的,供其他人使用;以及私有的,可更改的,具体的实现。调用方也很清楚,因为这些私有值根本不可用。
如果您正在集成一个使用locals()魔术的外部库,那么您应该对在哪里和如何使用它感到非常犹豫。我可能更愿意在任何其他可用选项的基础上修补代码。
发布于 2013-10-14 15:32:10
我在您的locals()代码片段中没有看到任何与迪尔“不可挑选”的内容。Dill可以序列化python中的几乎任何东西,还可以使用一些好工具来帮助您理解代码失败时导致您的酸洗失败的原因。只要django使用的是pickle而不是cPickle,要扩展泡菜来序列化像EllipsisType这样的东西,所要做的就是:
>>> import dill
>>> # this will enable python's pickle to pickle almost everything dill can pickle
>>>
>>> # on the full set of dill's types, this usually works unless there's a generator
>>> # or an interator-type or something odd like a traceback object in locals
>>> dill.loads(dill.dumps(locals()))
>>> ...
>>> # if you get a pickling error, use dill's tools to figure out a workaround
>>> dill.detect.badobjects(your_bad_object, depth=0)
>>> dill.detect.badobjects(your_bad_object, depth=1)
>>> ...如果您绝对愿意,可以使用dill的badobjects (或其他检测函数之一)递归地深入locals()引用链中的所有内容,并弹出不可选择的对象,而不是在每个深度调用它,如上面所示。
https://stackoverflow.com/questions/6834432
复制相似问题