在Python中,假设我有一个函数f,我想传递一些辅助参数(为简单起见,它只是第一个保持变量的参数).
这两种方式(如果有的话)之间有什么区别?
# Assume secondary_args and secondary_kwargs have been defined
import functools
g1 = functools.partial(f, *secondary_args, **secondary_kwargs)
g2 = lambda x: f(x, *secondary_args, **secondary_kwargs)
Run Code Online (Sandbox Code Playgroud)
例如,在doc页面中partial,有这样的引用:
partial在类中定义的对象的行为类似于静态方法,并且在实例属性查找期间不会转换为绑定方法.
如果用于从提供给类的参数(在构造函数中或稍后通过函数)中创建类方法,lambda方法是否会受此影响?
我想创建一个行为类似collections.defaultdict的类,而没有使用代码指定工厂.EG:而不是
class Config(collections.defaultdict):
pass
Run Code Online (Sandbox Code Playgroud)
这个:
Config = functools.partial(collections.defaultdict, list)
Run Code Online (Sandbox Code Playgroud)
这几乎可行,但是
isinstance(Config(), Config)
Run Code Online (Sandbox Code Playgroud)
失败.我打赌这个线索意味着还有更深层次的狡猾问题.那么有没有办法真正实现这一目标?
我也尝试过:
class Config(Object):
__init__ = functools.partial(collections.defaultdict, list)
Run Code Online (Sandbox Code Playgroud) def decorated(f):
@functools.wraps(f)
def wrapper():
return f()
return wrapper
@decorated
def g():
pass
Run Code Online (Sandbox Code Playgroud)
functools.wraps它的工作是保留以下名称g:
>>> g.__name__
'g'
Run Code Online (Sandbox Code Playgroud)
但是如果我传递一个参数g,我得到一个TypeError包含包装器的名称:
>>> g(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: wrapper() takes no arguments (1 given)
Run Code Online (Sandbox Code Playgroud)
这个名字来自哪里?它保存在哪里?有没有办法使异常看起来像g() takes no arguments?
考虑以下功能:
def f(x, dummy=list(range(10000000))):
return x
Run Code Online (Sandbox Code Playgroud)
如果我使用multiprocessing.Pool.imap,我会得到以下时间:
import time
import os
from multiprocessing import Pool
def f(x, dummy=list(range(10000000))):
return x
start = time.time()
pool = Pool(2)
for x in pool.imap(f, range(10)):
print("parent process, x=%s, elapsed=%s" % (x, int(time.time() - start)))
parent process, x=0, elapsed=0
parent process, x=1, elapsed=0
parent process, x=2, elapsed=0
parent process, x=3, elapsed=0
parent process, x=4, elapsed=0
parent process, x=5, elapsed=0
parent process, x=6, elapsed=0
parent process, x=7, elapsed=0
parent process, x=8, elapsed=0
parent process, …Run Code Online (Sandbox Code Playgroud) 我想测试一个我写的简单装饰器:
它看起来像这样:
#utilities.py
import other_module
def decor(f):
@wraps(f)
def wrapper(*args, **kwds):
other_module.startdoingsomething()
try:
return f(*args, **kwds)
finally:
other_module.enddoingsomething()
return wrapper
Run Code Online (Sandbox Code Playgroud)
然后我用python-mock测试它:
#test_utilities.py
def test_decor(self):
mock_func = Mock()
decorated_func = self.utilities.decor(mock_func)
decorated_func(1,2,3)
self.assertTrue(self.other_module.startdoingsomething.called)
self.assertTrue(self.other_module.enddoingsomething.called)
mock_func.assert_called_with(1,2,3)
Run Code Online (Sandbox Code Playgroud)
但它踢回来:
Traceback (most recent call last):
File "test_utilities.py", line 25, in test_decor
decorated_func = Mock(wraps=self.utilities.decor(mock_func))
File "utilities.py", line 35, in decor
@wraps(f)
File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper
setattr(wrapper, attr, getattr(wrapped, attr))
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 660, in __getattr__
raise AttributeError(name)
AttributeError: __name__
Run Code Online (Sandbox Code Playgroud)
我知道functools.wraps()只是一个帮手包装器.所以如果我把它拿出去测试就行了.
我可以让模拟玩functools.wraps()吗?
Python 2.7.3
在尝试使用装饰器更新函数的包装器时,我遇到了一个相当神秘的(至少对我来说)错误消息.我有什么想法可以解决这个问题吗?
我试图让我的代码尽可能通用,所以它也适用于其他情况.
def decorator(d):
"""Make function d a decorator: d wraps a function fn."""
def _d(fn):
return functools.update_wrapper(d(fn), fn)
functools.update_wrapper(_d, d)
return _d
@decorator
def f(fn):
"""Converts the string fn to a function and returns it.
Because of the @decorator decorator, _f.__name__ should
be identical to f.__name__"""
f.__name__ = fn
def _f(fn):
return eval(fn)
return _f
g = f('x**2')
print g.__name__
Run Code Online (Sandbox Code Playgroud)
期望的输出:
>>>x**2
Run Code Online (Sandbox Code Playgroud)
实际产量:
Traceback (most recent call last):
File "C:\python\swampy-2.0\testcode.py", line 18, in <module>
g = f('x**2')
File "C:\python\swampy-2.0\testcode.py", …Run Code Online (Sandbox Code Playgroud) 我导入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作为解释器
我在 Windows 上使用 Python 3.7
运行每个代码时都会出现此错误:
Traceback (most recent call last):
File "test.py", line 1, in <module>
import nltk
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\nltk\__init__.py", line 99, in <module>
from nltk.internals import config_java
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\nltk\internals.py", line 11, in <module>
import subprocess
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 50, in <module>
import signal
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\signal.py", line 3, in <module>
from functools import wraps as _wraps
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\functools.py", line 21, in <module>
from collections import namedtuple
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\collections\__init__.py", line 22, in <module>
from keyword import iskeyword as _iskeyword
File …Run Code Online (Sandbox Code Playgroud) 在我的代码中,我有以下类:
class A:
@functools.singledispatchmethod
def handle(arg):
pass
Run Code Online (Sandbox Code Playgroud)
我希望其他类继承A并重载通用方法,handle如下所示:
class B(A):
@handle.register
def handle_int(arg: int):
return arg + 2
Run Code Online (Sandbox Code Playgroud)
但是,我收到错误:
未解析的引用“句柄”
如何在基类中创建这个通用方法?(我不想在每个子类中创建此函数来使用singledispatchmethod。)
我正在阅读有关函数在设置为类 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)
我有点期望他们都会有同样的行为方式。
functools ×10
python ×10
python-3.x ×4
decorator ×2
partial ×2
class ×1
generics ×1
import ×1
lambda ×1
mocking ×1
python-2.7 ×1
unit-testing ×1