- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设您有一个带有许多(关键字)参数的类,其中大部分要存储为实例变量:
class ManyInitVariables():
def __init__(a=0, b=2, c=1, d=0, e=-1, ... , x=100, y=0, z=9):
如何在 __init__
中初始化它们?你可以这样做:
class ManyInitVariables():
def __init__(a=0, b=2, c=1, d=0, e=-1, ... , x=100, y=0, z=9):
self.a = a
self.b = b
self.c = c
...
self.z = z
...但这需要大量输入!我怎样才能让 __init__
自动一些它需要的参数,注意其他参数可能不需要分配为实例变量?
最佳答案
我敢肯定,对于这个非常常见的问题,网络上还有许多其他类似的解决方案,但这是一个,例如:
import functools
import inspect
def absorb_args(f):
args, _, _, defs = inspect.getargspec(f)
args = args[1:] # ignore the leading `self`
@functools.wraps(f)
def do_absorb(self, *a, **k):
ndefs = len(args) - len(a) + 2
for name, value in zip(args, a + defs[-ndefs:]):
setattr(self, name, value)
for name, value in k.items():
setattr(self, name, value)
return f(self, *a, **k)
return do_absorb
补充:我被要求进一步解释这一点,但是,如果你不擅长 Python,这里有很多事情要做!-)。
functools.wraps
是一个装饰器,可以帮助制作更好的装饰器,参见 https://docs.python.org/2/library/functools.html#functools.wraps -- 与问题没有直接关系,但有助于支持交互式 help
和基于函数文档字符串的工具。在编写(最常见的情况)包装被装饰函数的函数装饰器时,养成总是使用它的习惯,您不会后悔的。
inspect
模块是在现代 Python 中进行内省(introspection)的唯一正确方法。 inspect.getargspec
特别为您提供有关函数接受哪些参数的信息,以及它们的默认值是什么(如果有的话)(我忽略的两位信息,通过将它们分配给 _
,是关于 *a
和 **k
特殊参数,这个装饰器不支持)。参见 https://docs.python.org/2/library/inspect.html?highlight=getargspec#inspect.getargspec了解更多。
self
始终是方法的第一个参数(并且此装饰器仅用于方法:-)。因此,第一个 for
循环处理位置参数(无论是在调用中明确给出还是默认为默认值);然后,第二个 for
循环处理命名参数(我希望那个更容易掌握:-)。 setattr
当然是珍贵的内置函数,它用变量名设置属性,https://docs.python.org/2/library/functions.html?highlight=setattr#setattr了解更多。
顺便说一句,如果你只关心在 __init__
中使用它(正如你在下面的例子中看到的,absorb_attrs
本身没有这样的约束),那么写一个 < strong>class 装饰器,它为这种处理挑选出类的 __init__
,并将该类装饰器应用于类本身。
此外,如果您的类的 __init__
一旦以这种方式“吸收”了 args 就没有工作要做,您仍然必须定义(修饰的)__init__
,但是它的主体可以限制为解释参数的文档字符串(我个人更喜欢在这种情况下总是也有一个 pass
语句,但这是个人风格问题)。
现在,回到原来的答案,举个例子...!-)
然后,例如,类似
class Struggle(object):
@absorb_args
def __init__(self, a, b, c, bab='bo', bip='bop'):
self.d = a + b
@absorb_args
def setit(self, x, y, z, u=23, w=45):
self.t = x + y
def __str__(self):
attrs = sorted(self.__dict__)
r = ['%s: %s' % (a, getattr(self, a)) for a in attrs]
return ', '.join(r)
s = Struggle('fee', 'fie', 'foo', bip='beeeeeep')
s.setit(1, 2, 3, w=99)
print(s)
会打印
a: fee, b: fie, bab: bo, bip: beeeeeep, c: foo, d: feefie, t: 3, u: 23, w: 99, x: 1, y: 2, z: 3
根据需要。
我以这种方式“重新发明轮子”(而不是在网上搜索解决方案)的唯一借口是那天晚上我的妻子和合著者安娜(唯一一位因对Python 社区,顺便说一句:-) 问了我这个问题(我们正在慢慢写“Python in a Nutshell”的第 3 版)——我花了 10 分钟来编写这个代码(抱歉,还没有测试:- ) 而在同样的 10 分钟内,她(尽管她是一个非常熟练的网络搜索者:-) 无法在网络上找到现有的解决方案。而且,这样我就不必担心版权问题,如果我想在这里发布它,将它包含在下一个 Nutshell 中,在 OSCON 或 Pycon 上展示它,等等...:-)
关于python - 如何优雅/高效地为需要大量实例变量的 Python 类编写 __init__ 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28004358/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!