为什么是这样:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyList(list, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)
好的,按预期工作:
created <class '__main__.MyMixin'>
created <class '__main__.MyList'>
Run Code Online (Sandbox Code Playgroud)
但是这个:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyObject(object, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)
不行,并且如此爆炸?:
created <class '__main__.MyMixin'>
Traceback (most recent call last):
File "/tmp/junk.py", line 11, in <module>
class MyObject(object, MyMixin): pass
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order …Run Code Online (Sandbox Code Playgroud) 我想在bash脚本中嵌入短python脚本的文本,比如说,我的.bash_profile.做这样的事情最好的方法是什么?
我到目前为止的解决方案是使用-c选项调用python解释器,并告诉解释器exec它读取的内容stdin.从那里,我可以构建如下的简单工具,允许我处理文本以在我的交互式提示中使用:
function pyexec() {
echo "$(/usr/bin/python -c 'import sys; exec sys.stdin.read()')"
}
function traildirs() {
pyexec <<END
trail=int('${1:-3}')
import os
home = os.path.abspath(os.environ['HOME'])
cwd = os.environ['PWD']
if cwd.startswith(home):
cwd = cwd.replace(home, '~', 1)
parts = cwd.split('/')
joined = os.path.join(*parts[-trail:])
if len(parts) <= trail and not joined.startswith('~'):
joined = '/'+joined
print joined
END
}
export PS1="\h [\$(traildirs 2)] % "
Run Code Online (Sandbox Code Playgroud)
这种方法虽然闻起来有点滑稽,但我想知道这样做的替代方法可能是什么.
我的bash脚本编写技巧非常简陋,所以我特别感兴趣的是,从bash解释器的角度来看,我是否正在做一些愚蠢的事情.
我想为模板本身内部的Jinja模板中使用的变量设置默认值.看看Jinja2文档,我认为没有办法做到这一点.我错过了什么吗?我看到了"默认"过滤器,但我希望将值模板设置为宽而不是逐个使用.
我花了一个小时左右的时间尝试自学足够的Jinja2扩展编写过程来编写扩展标记setdefault,看起来像这样:
{% setdefault animal = 'wumpas' %}
Run Code Online (Sandbox Code Playgroud)
set如果指定的名称未定义,则期望的效果将等同于标记,但如果已定义指定的名称,则无效.因此,我无法让这个工作.
我的工作是完全绕过jinja并制作复合文件; 特殊标记之前的区域是默认值的(yaml)映射,标记之后的区域是jinja模板.这个似乎工作得很好的概念证明实现是:
skel_text = """\
animal: wumpas
%%
The car carried my {{animal}} to the vet.
"""
class Error(Exception): pass
_skel_rx = re.compile(
r"""((?P<defaults>.*?)^%%[ \t]*\n)?(?P<template>.*)""",
re.MULTILINE|re.DOTALL)
_env = jinja2.Environment(trim_blocks=True)
def render(skel, **context):
m = _skel_rx.match(skel_text)
if not m:
raise Error('skel split failed')
defaults = yaml.load(m.group('defaults') or '{}')
template = _env.from_string(m.group('template') or '')
template.globals.update(defaults)
return template.render(**context)
print render(skel_text)
print render(skel_text, animal='cat')
Run Code Online (Sandbox Code Playgroud)
那么,有没有办法在库存中使用等效的Jinja2,或者如何编写扩展来实现所需的效果呢?
我已经开始在我编写的代码中更广泛地使用python描述符协议.通常,默认的python查找魔法是我想要发生的,但有时我发现我想获取描述符对象本身而不是其__get__方法的结果.想知道描述符的类型,或者描述符中存储的访问状态,或者某些东西.
我编写了下面的代码,以我认为正确的顺序遍历名称空间,并返回属性raw,无论它是否是描述符.我很惊讶,虽然我无法在标准库中找到内置函数或其他内容来实现这一点 - 我认为它必须在那里,我只是没有注意到它或用Google搜索正确的搜索词.
python发行版中的某个地方是否有功能(或类似的东西)?
谢谢!
from inspect import isdatadescriptor
def namespaces(obj):
obj_dict = None
if hasattr(obj, '__dict__'):
obj_dict = object.__getattribute__(obj, '__dict__')
obj_class = type(obj)
return obj_dict, [t.__dict__ for t in obj_class.__mro__]
def getattr_raw(obj, name):
# get an attribute in the same resolution order one would normally,
# but do not call __get__ on the attribute even if it has one
obj_dict, class_dicts = namespaces(obj)
# look for a data descriptor in class hierarchy; it takes priority over …Run Code Online (Sandbox Code Playgroud) 当我easy_install有一些python模块时,警告如:
<some module>: module references __file__
<some module>: module references __path__
<some module>: module MAY be using inspect.trace
<some module>: module MAY be using inspect.getsourcefile
Run Code Online (Sandbox Code Playgroud)
有时会被释放.
这些消息来自哪个(什么包/源文件)?为什么引用__file__或被__path__认为是坏事?