我导入functools后,我从解释器收到这样的消息:
回溯(最近一次调用最后一次):文件"C:/Users/Admin/Documents/Python/decorator.py",第1行,在导入functools文件"C:\ Python3\lib\functools.py",第22行,in从类型导入MappingProxyType ImportError:无法导入名称'MappingProxyType'
import functools
def trace(func):
def inner(*args, **kwargs):
print(func.__name__, args, kwargs)
return func(*args, **kwargs)
functools.update_wrapper(inner, func)
return inner
@trace
def foo(x):
return x
foo(42)
Run Code Online (Sandbox Code Playgroud)
使用PyCharm作为IDE,使用CPython作为解释器
我正在阅读有关函数在设置为类 atrributes 时如何成为绑定方法的内容。然后我观察到,对于 . 包装的函数来说情况并非如此functools.partial。对此有何解释?
简单的例子:
from functools import partial
def func1():
print("foo")
func1_partial = partial(func1)
class A:
f = func1
g = func1_partial
a = A()
a.f() # TypeError: func1() takes 0 positional arguments but 1 was given
a.g() # prints "foo"
Run Code Online (Sandbox Code Playgroud)
我有点期望他们都会有同样的行为方式。
我经常使用namedtuple类.我一直在想今天是否有一种很好的方法来为这样的类实现自定义排序,即使默认排序键不是namedtuple的第一个元素(然后是第二个,第三个等).
我的第一直觉是实现__lt__并__eq__让total_ordering剩下的工作完成(它填写了le,ne,gt,ge):
from collections import namedtuple
from functools import total_ordering
@total_ordering
class B(namedtuple('B', 'x y')):
def __lt__(self, other):
return self.y < other.y
Run Code Online (Sandbox Code Playgroud)
然而:
def test_sortingB():
b1 = B(1, 2)
b2 = B(2, 1)
assert b2 < b1 # passes
assert b2 <= b1 # fails
Run Code Online (Sandbox Code Playgroud)
哦,对...... 如果缺少total_ordering其他方法,则只填写其他方法.由于tuple/namedtuple有这样的方法,total_ordering对我没有任何作用.
所以我想我的选择是
关于解决这个问题的最佳方法的建议?
我Functools.update_wrapper()在装饰器中使用,但似乎update_wrapper只重写函数属性(如__doc__,__name__),但不影响help()函数.
我知道这些答案,但它们不适用于装饰器类.
这是我的功能.
import functools
class memoized(object):
def __init__(self, func):
self.func = func
functools.update_wrapper(self, func)
def __call__(self, *args):
self.func(*args)
@memoized
def printer(arg):
"This is my function"
print arg
Run Code Online (Sandbox Code Playgroud)
这是输出
>>> printer.__doc__
This is my function
>>> help(printer)
Help on memoized in module __main__ object:
printer = class memoized(__builtin__.object)
| Methods defined here:
|
| __call__(self, *args)
|
| __init__(self, func)
|
| ----------------------------------------------------------------------
| Data descriptors defined here: …Run Code Online (Sandbox Code Playgroud) 如果我定义我的功能如下:
def myfunc(arg1, arg2):
pass
Run Code Online (Sandbox Code Playgroud)
然后myfunc == myfunc会回来True
但functools.partial(myfunc, arg2=1) == functools.partial(myfunc, arg2=1)会回来False.
为了单元测试的目的,是否有一种简单的方法来测试部分功能是否是我期望的功能?
是否有内置函数或标准库函数大致相当于
def recur_until(start, step_fu, stop_predicate=lambda _: False):
current = start
while not stop_predicate(current):
yield current
current = step_fu(current)
Run Code Online (Sandbox Code Playgroud)
要么
def recur_while(start, step_fu, predicate=lambda _: True):
current = start
while predicate(current):
yield current
current = step_fu(current)
Run Code Online (Sandbox Code Playgroud)
甚至只是
def recur(start, step_fu):
current = start
while True:
yield current
current = step_fu(current)
Run Code Online (Sandbox Code Playgroud)
在任何版本的Python?(当与之结合时,后者与其他两个一样好itertools.takewhile.)
像这样的生成器函数将允许迭代地计算某些递归定义的序列,即一阶递归关系.
虽然这些在需要时不太难实现,但我觉得像他们这样的东西应该是itertools或者可能的functools一部分,但如果是的话,我还没有在文档中发现它.
list(recur_until(2, lambda x: x**2 - 1, lambda x: x > 1e4))
# [2, 3, 8, 63, 3968]
Run Code Online (Sandbox Code Playgroud)
还应该使用非数字元素:
list(recur_until('', lambda x: …Run Code Online (Sandbox Code Playgroud) 我知道一定有办法做到这一点。但我收到错误“TypeError:第一个参数必须可调用”。
我可以采取哪些不同的措施来完成这项工作?
class FaxMachine(object):
MODEL_NO = '100'
@staticmethod
def load_fax(fax, error=''):
# send fax here
fail_fax = functools.partial(load_fax, error='PC LOAD LETTER')
Run Code Online (Sandbox Code Playgroud) 我发现functoolsPython 3的模块有两个非常相似的方法:partial和partialmethod.
有人可以提供使用每个人的好例子吗?
我想以类似于它们在带有列表的本机 python 中应用的方式在 Pandas 中使用reduce和accumulate函数。在itertools 和functools 实现中,reduce 和accumulate(在其他语言中有时称为fold 和cumulative fold)需要一个带有两个参数的函数。在 Pandas 中,没有类似的实现。该函数有两个参数:f(accumulated_value,popped_value)
所以,我有一个二进制变量列表,并想计算我们处于 1 状态时的持续时间数:
In [1]: from itertools import accumulate
import pandas as pd
drawdown_periods = [0,1,1,1,0,0,0,1,1,1,1,0,1,1,0]
Run Code Online (Sandbox Code Playgroud)
使用 lambda 函数将累积应用于此
lambda x,y: (x+y)*y
Run Code Online (Sandbox Code Playgroud)
给
In [2]: list(accumulate(drawdown_periods, lambda x,y: (x+y)*y))
Out[2]: [0, 1, 2, 3, 0, 0, 0, 1, 2, 3, 4, 0, 1, 2, 0]
Run Code Online (Sandbox Code Playgroud)
计算每个 drawdown_period 的长度。
有没有一种聪明但古怪的方法来提供带有两个参数的 lambda 函数?我可能在这里错过了一个技巧。
我知道 groupby 有一个可爱的配方(参见StackOverflow 如何计算 Pandas 中的连续相等值/如何使用 series/dataframe 模拟 itertools.groupby)。我会重复一遍,因为它太可爱了:
In [3]: df = pd.DataFrame(data=drawdown_periods, columns=['dd']) …Run Code Online (Sandbox Code Playgroud) 我想知道为什么默认情况下不继承包装方法/函数的元数据(例如__name__, )。相反,提供该功能。__doc__partialfunctoolsupdate_wrapper
为什么默认情况下不这样做并没有在任何地方提到(据我所知),例如这里和许多functools.partial关于如何“解决问题”的教程__name__。
是否有继承此信息会导致问题/混乱的示例?
functools ×10
python ×10
python-3.x ×2
class ×1
decorator ×1
import ×1
namedtuple ×1
pandas ×1
python-2.7 ×1
recurrence ×1
recursion ×1
sorting ×1