任何类似宏的构造/技术/技巧? [英] any macro-like construct/technique/trick?

查看:62
本文介绍了任何类似宏的构造/技术/技巧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法模仿C / C ++的预处理器对于
宏的行为?问题:很多这样的代码:


def foo():

#....做一些东西

如果调试:

emit_dbg_obj(DbgObjFoo(a,b,c))


#....做更多的东西

如果调试:

emit_dbg_obj(DbgObjBar(d,e))


#...依此类推......

注意:


*两行调试条件往往会真正分解流程

的周围代码


*在C中你可以用宏包装它们,这样你就可以用宏来实例化

DEBUG_EMIT(DbgObjFoo(a,b,c))等等br />
对象并在设置调试标志时对其进行处理。使用

def debug_emit(obj)时,单行

在视觉上不会造成太大的破坏性:
def debug_emit(obj):

如果调试:

emit_dbg_obj(obj)

是一个糟糕的解决方案,因为* *总是*实例化DbgObj *,即使在

不需要;我想避免这种不必要的浪费

Is there a way to mimic the behaviour of C/C++''s preprocessor for
macros? The problem: a lot of code like this:

def foo():
# .... do some stuff
if debug:
emit_dbg_obj(DbgObjFoo(a,b,c))

# .... do more stuff
if debug:
emit_dbg_obj(DbgObjBar(d,e))

# ... and so on ...

Notes:

* the two-lines of debug conditional tend to really break up the flow
of the surrounding code

* in C you could wrap them with a macro so you could do
DEBUG_EMIT(DbgObjFoo(a,b,c)), etc, with the macro only instantiating
the object and processing it if the debug flag was set. The one-liner
is MUCH less disruptive visually when reading code

* using
def debug_emit(obj):
if debug:
emit_dbg_obj(obj)
is a poor solution, because it *always* instantiates DbgObj*, even when
not needed; I want to avoid such unnecessary waste

推荐答案

是否必须阅读两行真的比一行更糟糕?而对于最明显的解决方案,你唯一感到讨厌的是什么?

如果是这样的话,那么问题是什么:


def foo():

#....做一些东西

如果调试:emit_dbg_obj(DbgObjFoo(a,b,c))

#....做更多的东西


在我看来,这不是那么可读,也没有比

DEBUG_EMIT(DbgObjFoo( ,b,c))然后再说一遍,我不介意两行

版本 - 就个人而言,我更喜欢我的调试代码更显眼而不是比b / b更少,从代码的功能部分来看,它在视觉上和心理上是明显分离的。


预处理器宏及其同类似乎总是很糟糕

kludge给我,nessecary和C语言有用,我会授予,但

根本不是Pythonic。


如果你真的觉得你不能忍受(大概是边际的)费用

在联合国创建调试对象时nessecary,并希望有条件地摆脱某些代码行 - 使用文本替换,这实际上,根据我的有限理解,所有预处理器都是 - b


然后为什么不自己动手呢?在您的开发中使用

emit_dbg_obj(DbgObjFoobar(a,b,c))所有你想要的代码,并使用简单的正则表达式搜索并替换它来评论它

代码发货时你的来源。


但最重要的是,如果你担心效率问题这个

细粒度,试图搜寻每个最后一个字节的内存,我建议

Python可能是你的问题的错误语言。对象创建

开销等只是具有高级动态解释语言的常规成本的一部分。如果你确实需要

预处理器宏出于效率原因,那么你可能需要C.


对不起,我的回复还没有一直都是有用的我猜:)这个邮件列表似乎是一个趋势

- 要求一些功能,或者一种方式来支付
模仿它,而不是得到一堆争论为什么这个特征

不适合该语言的设计和哲学,以及一些关于如何以不同方式做事的建议。 br />

可能一些知识渊博的Pythonista可以通过使用exec或eval或其他类似的方式来实现你想要的行为。

难看的黑客...但我只能希望这种做法不会变得很普遍。



Mac写道:
Is having to read two lines really that much worse than one? And the
only thing you find objectionable about the most obvious solution?
If so, then what''s wrong with:

def foo():
# .... do some stuff
if debug: emit_dbg_obj(DbgObjFoo(a,b,c))
# .... do more stuff

To my mind, this is no less readable and no more clutter than
DEBUG_EMIT(DbgObjFoo(a,b,c)) Then again, I don''t mind the two line
version - personally, I prefer my debug code be more conspicuous rather
than less, so that its clearly seperate, visually and hence mentally,
from functional part of the code.

Preprocessor Macros and their ilk have always seemed like an awful
kludge to me, nessecary and useful in a language like C I''ll grant, but
not very Pythonic at all.

If you really feel you can''t stand the (presumably marginal) expense of
creating the debug objects when unnessecary, and want to get rid of
certain lines of code conditionally - using textual replacement, which
is essentially, by my limited understanding, all a pre-processor does -
then why not just do it yourself? Have
emit_dbg_obj(DbgObjFoobar(a,b,c)) all you want in your in development
code, and use a simple regex search and replace to comment it out of
your source when the code ships.

Most critically, though, if you''re worried about efficiency issues this
fine-grained, trying to scrounge every last byte of memory, I''d suggest
Python is probably the wrong language for your problem. Object creation
overhead and the like is just part of the regular cost of having a high
level, dynamic, interpreted language. If you really, really need
preprocessor macros for efficiency reasons, then your probably need C.

I''m sorry, my reply hasn''t been all that helpful I guess :) It seems a
bit of a trend on this mailing list - ask for some feature, or a way to
emulate it, and instead get a bunch of arguments as to why that feature
doesn''t fit the design and philosophy of the language, and some
suggestions on how to do things differently.

Probably some much more knowledgable Pythonista can cook up a way to
achieve your desired behaviour, using exec or eval or some other such
unsightly hack... but I can only hope such practices don''t become
widespread.


Mac wrote:
有没有办法模仿C / C ++的
宏预处理器的行为?问题:很多这样的代码:

def foo():
#....做一些事情
如果调试:
emit_dbg_obj(DbgObjFoo( a,b,c))
#....做更多的东西
如果调试:
emit_dbg_obj(DbgObjBar(d,e))
#...依旧......

注意:

*两行调试条件往往真正打破了流程的流程周围的代码

*在C中,你可以用宏包装它们,这样你就可以用宏来实现 DEBUG_EMIT(DbgObjFoo(a,b,c))等等>对象并在设置调试标志时对其进行处理。使用
def debug_emit(obj)时,单行
在视觉上不那么具有破坏性:
如果调试:
emit_dbg_obj(obj) )
是一个糟糕的解决方案,因为* *总是*实例化DbgObj *,即使不需要
;我想避免这种不必要的浪费
Is there a way to mimic the behaviour of C/C++''s preprocessor for
macros? The problem: a lot of code like this:

def foo():
# .... do some stuff
if debug:
emit_dbg_obj(DbgObjFoo(a,b,c))

# .... do more stuff
if debug:
emit_dbg_obj(DbgObjBar(d,e))

# ... and so on ...

Notes:

* the two-lines of debug conditional tend to really break up the flow
of the surrounding code

* in C you could wrap them with a macro so you could do
DEBUG_EMIT(DbgObjFoo(a,b,c)), etc, with the macro only instantiating
the object and processing it if the debug flag was set. The one-liner
is MUCH less disruptive visually when reading code

* using
def debug_emit(obj):
if debug:
emit_dbg_obj(obj)
is a poor solution, because it *always* instantiates DbgObj*, even when
not needed; I want to avoid such unnecessary waste






在我写完帖子后,我意识到我没有提供足够的背景

我正在做什么,因此对于任何读者来说,为什么这么做都不太清楚

我会想要这个。要点就是这个。我有许多执行相同任务的算法

。我正在尝试评估哪些更好用

在哪种情况下,这意味着我正在计时(感兴趣的是
*相对*速度,所以Python是上可接受的)。我还有第二个应用程序

,它允许我观察所述算法的操作由

消耗这些发出的调试对象并在其中以图形方式显示

信息。我在观察具有非常精细的粒度,

这意味着几乎每一行都会发出一个调试对象。<​​br />
当然,如果每一行都是调试代码(或者更糟,如上所述) ,1

系列实际代码,2行调试代码),

算法的可读性是可怕的,使得进一步的开发成为一种痛苦。因为,当我没有观察到算法时,我会计算它们,我希望

调试/观察代码对运行时的影响最小;

实例化其中一些调试对象相当昂贵。


在那里,希望这可以更好地描述我的动机。如果

任何人都可以建议替代方式来构造这样的代码,我会全都耳朵

(......好吧,眼睛,真的......)/ br / >

您提出的将代码单行列为if debug:emit _.....

发生在我身上,但出于可读性的原因,我想要在视觉上*短*

a行,所以它不会减损其他代码。 C

预处理器在这种缩短中特别有用。 (例如,

print" foo" ;; DBG(DbgObj(..)); print" bar";)


嗯,这个设置你不可能比DebugObject的实例化更短......这给了我一个想法......if debug:可以将
放在DebugObjectBase中,并且所有的DebugObject都继承自

它......不......等等......没问题,问题是以下情况:

...

#真实代码行

DbgObjFoo(a,b,expensive_function(c))

#真正的代码行


在调试/观察运行中,调试对象偶尔会有外部计算的构造函数值,如上所述,

建议的解决方案不会让我们免于昂贵的计算。

After I wrote my post I realized I didn''t provide enough context of
what I''m doing, hence it is not quite clear to any readers why the heck
I would want this. The gist is this. I have a number of algorithms
that perform the same task. I''m trying to assess which ones work better
under which circumstances, which means I''m timing them (interested in
*relative* speed, so Python is acceptable). I also have a second app
which allows me to "observe" the operation of said algorithms by
consuming such emitted debug objects and graphically displaying the
information therein. I''m "observing" with a very fine granularity,
which means a debug object is emitted between almost every single line.
Naturally, if every second line is debug code (or worse, as above, 1
line of real code, 2 lines of debug code), the readability of the
algorithm is horrendous, making further development a pain. Since,
when I''m NOT observing the algorithms then I''m timing them, I want the
debug/observe code to have minimal impact on the runtimes;
instantiating some of these debug objects is rather costly.

There, hopefully this gives a better picture of my motivation. If
anyone can suggest alternate way to structure such code, I''m all ears
(... well, eyes, really... :)

Your proposal for one-lining the code as "if debug: emit_....."
occurred to me, but for readability reasons I want as visually *short*
a line as possible, so it doesn''t detract from the other code. The C
preprocessor was particularly helpful in such "shortening". (e.g.,
print "foo"; DBG(DbgObj(..)); print "bar";)

Hmm, with this setup you can''t get any shorter than the instantiation
of the DebugObject... which gives me an idea... the "if debug:" could
be placed within DebugObjectBase, and all the DebugObjects inherit from
it... no... wait... no good, the problem is the following case:
...
# real line of code
DbgObjFoo(a,b,costly_function(c))
# real line of code

On a debugging/observing run, the debugging objects occasionally have
their constructor values computed externally, as above, and the
proposed solution would not save us from that costly computation.


Mac写道:
是否存在一种模仿C / C ++的宏预处理器行为的方法?


没有标准或普遍接受的方式。


你可以像Jordan Rastrick建议的那样做并写自己的排序,或者使用现有的预处理器。使用新的导入

钩子你可以自动进行转换,

尽管我犹豫不决,你可能会这样做。

这通常是一个坏主意,因为你实质上是在创造一种类似但不是Python的新语言,这使得人们更难理解

发生了什么。

问题:这样的代码很多:

def foo():
#....做一些东西
如果调试:
emit_dbg_obj(DbgObjFoo(a,b,c))
... *调试条件的两行往往真正打破了流程的流程
周围的代码


如果流量是你唯一关注的问题,你可以有一个无所事事的

功能,并且在顶部有


如果调试:

emit = emit_dbg_obj

else:

def emit(* args,** kwargs):pass


然后将所有代码写成


emit(DbgObjFoo(a,b,c))

*使用
def debug_emit(obj):
如果调试:
emit_dbg_obj(obj)
是一个糟糕的解决方案,因为* *总是*实例化DbgObj *,即使
不需要;我想避免这种不必要的浪费
Is there a way to mimic the behaviour of C/C++''s preprocessor for
macros?
There are no standard or commonly accepted ways of doing that.

You could do as Jordan Rastrick suggested and write your own sort
of preprocessor, or use an existing one. With the new import
hooks you can probably make the conversion happen automatically,
though I hesitate suggestions that as you might actually do that.
It''s typically a bad idea because you''re in essence creating a
new language that is similar to but not Python, making it harder
for people to understand what''s going on.
The problem: a lot of code like this:

def foo():
# .... do some stuff
if debug:
emit_dbg_obj(DbgObjFoo(a,b,c)) ... * the two-lines of debug conditional tend to really break up the flow
of the surrounding code
If flow is your only concern you can have a do-nothing
function and at the top have

if debug:
emit = emit_dbg_obj
else:
def emit(*args, **kwargs): pass

then write all your code as

emit(DbgObjFoo(a,b,c))
* using
def debug_emit(obj):
if debug:
emit_dbg_obj(obj)
is a poor solution, because it *always* instantiates DbgObj*, even when
not needed; I want to avoid such unnecessary waste




当然这也会有用。


废物有多糟糕?这真的是一个问题吗?


你所有的表格代码


emit(Class(constructor,args))


?如果是这样,你的debug_emit可能看起来像


debug_emit(klass,* args,** kwargs):

如果调试:

emit_dbg_obj(klass(* args,** kwargs))


并使用


debug_emit(DbgObjFoo,a,b, c)

debug_emit(DbgObjBar,d,e)


虽然我会使用我写的无操作函数版本

更早,因为,* ahem *,它避免了额外的如果调试:的不必要的浪费

校验。 :)


Andrew
da***@dalkescientific.com



That would work as well of course.

How bad is the waste? Is it really a problem?

Is all your code of the form

emit(Class(constructor, args))

? If so, your debug_emit could be made to look like

debug_emit(klass, *args, **kwargs):
if debug:
emit_dbg_obj(klass(*args, **kwargs))

and used

debug_emit(DbgObjFoo, a, b, c)
debug_emit(DbgObjBar, d, e)

though I would use the do-nothing function version I sketched
earlier because, *ahem*, it avoids an unnecessary waste of
the extra "if debug:" check. :)

Andrew
da***@dalkescientific.com


这篇关于任何类似宏的构造/技术/技巧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆