我想在函数上使用一个装饰器,我将随后传递给一个多处理池.但是,代码失败了"PicklingError:无法pickle:属性查找__builtin__.function failed".我不太明白为什么它在这里失败了.我确信它很简单,但我找不到它.下面是一个最小的"工作"示例.我认为使用该functools功能足以让这个工作.
如果我注释掉功能装饰,它的工作没有问题.multiprocessing我在这里误会是什么意思?有没有办法让这项工作?
编辑:添加可调用的类装饰器和函数装饰器之后,事实证明函数装饰器按预期工作.可调用类装饰器继续失败.什么是可调用的类版本,使其不被腌制?
import random
import multiprocessing
import functools
class my_decorator_class(object):
def __init__(self, target):
self.target = target
try:
functools.update_wrapper(self, target)
except:
pass
def __call__(self, elements):
f = []
for element in elements:
f.append(self.target([element])[0])
return f
def my_decorator_function(target):
@functools.wraps(target)
def inner(elements):
f = []
for element in elements:
f.append(target([element])[0])
return f
return inner
@my_decorator_function
def my_func(elements):
f = []
for element in elements:
f.append(sum(element))
return f
if __name__ == …Run Code Online (Sandbox Code Playgroud) 显然,快速搜索会在Python中产生一百万个memoization装饰器的实现和风格.但是,我感兴趣的是一种我无法找到的味道.我希望它能够使存储值的缓存具有固定容量.添加新元素时,如果达到容量,则删除最旧的值并替换为最新值.
我担心的是,如果我使用memoization来存储很多元素,那么程序会因为缺少内存而崩溃.(我不知道这种担忧在实践中有多好.)如果缓存的大小固定,那么内存错误就不是问题.我工作的许多问题随着程序的执行而发生变化,因此初始缓存的值看起来与以后的缓存值非常不同(以后不太可能再次发生).这就是为什么我希望最新的东西被最新的东西取代.
我找到了这个OrderedDict类和一个示例,展示了如何将其子类化以指定最大大小.我想将它用作我的缓存,而不是正常dict.问题是,我需要memoize装饰器来获取一个名为maxlendefaults 的参数None.如果是None,那么缓存是无限的并且正常运行.任何其他值都用作缓存的大小.
我希望它像以下一样工作:
@memoize
def some_function(spam, eggs):
# This would use the boundless cache.
pass
Run Code Online (Sandbox Code Playgroud)
和
@memoize(200) # or @memoize(maxlen=200)
def some_function(spam, eggs):
# This would use the bounded cache of size 200.
pass
Run Code Online (Sandbox Code Playgroud)
下面是我到目前为止的代码,但是我没有看到如何将参数传递给装饰器,同时使它既可以"裸"又可以使用参数.
import collections
import functools
class BoundedOrderedDict(collections.OrderedDict):
def __init__(self, *args, **kwds):
self.maxlen = kwds.pop("maxlen", None)
collections.OrderedDict.__init__(self, *args, **kwds)
self._checklen()
def __setitem__(self, key, value):
collections.OrderedDict.__setitem__(self, key, value)
self._checklen()
def _checklen(self):
if self.maxlen is not None: …Run Code Online (Sandbox Code Playgroud) 我知道函数可以有属性.所以我可以做到以下几点:
def myfunc():
myfunc.attribute += 1
print(myfunc.attribute)
myfunc.attribute = 1
Run Code Online (Sandbox Code Playgroud)
是否可以通过任何方式使这样的函数表现得好像它是一个实例?例如,我希望能够做到这样的事情:
x = clever_wrapper(myfunc)
y = clever_wrapper(myfunc)
x.attribute = 5
y.attribute = 9
x() # I want this to print 6 (from the 5 plus increment)
y() # I want this to print 10 (from the 9 plus increment)
Run Code Online (Sandbox Code Playgroud)
就目前而言,该函数只有一个"实例",因此attribute只存在一次.通过任一修改x或y更改相同的值.我希望他们每个人都有自己的attribute.这有可能吗?如果是这样,你能提供一个简单,实用的例子吗?
重要的是我能够attribute从函数内部进行访问,但具有attribute不同的值,具体取决于调用函数的"实例".本质上,我想使用attribute它好像它是函数的另一个参数(这样它可以改变函数的行为)但不传递它.(假设函数的签名是固定的,所以我不能改变参数列表.)但我需要能够设置不同的值attribute,然后按顺序调用函数.我希望这是有道理的.
主要答案似乎是说要做这样的事情:
class wrapper(object):
def __init__(self, target):
self.target = target
def __call__(self, *args, **kwargs): …Run Code Online (Sandbox Code Playgroud) 使用Raphael JavaScript库时,如何找到纸张/画布的绝对位置?
例如,假设最小工作示例如下:
<html>
<head>
<script type="text/javascript" src="raphael.js"></script>
<script>
window.onload = function() {
var size = 600;
var paper = new Raphael(document.getElementById("canvas_container"),
size, size);
var c = paper.circle(100, 100, 50).attr({fill: "#00f"});
var x = 0; // get the paper's absolute x coordinate
var y = 0; // get the paper's absolute y coordinate
document.getElementById("coordinates").innerHTML = x + " " + y;
};
</script>
<style type="text/css">
#canvas_container {
width: 600px;
margin-left: auto;
margin-right: auto;
border: 1px solid #aaa;
}
</style>
</head> …Run Code Online (Sandbox Code Playgroud) python ×3
decorator ×2
attributes ×1
css-position ×1
function ×1
html5-canvas ×1
javascript ×1
memoization ×1
raphael ×1