有没有理由不这样做? [英] Is there a reason not to do this?

查看:68
本文介绍了有没有理由不这样做?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我发现有关Python的烦恼之一就是当你对方法定义做出改变时,改变现状并没有反映出来。

一个类的实例(因为你真的在定义一个新类时,你重新加载一个类定义,而不是实际重新定义它)。所以我用这种编程风格来了




def defmethod(cls):

return lambda(func):type .__ setattr __(cls,func.func_name,func)

class c1(object):pass


@defmethod(c1)

def m1(self,x):...

现在,如果重新定义m1,现有的c1实例将看到更改。


我的问题是:有没有理由不这样做?在幕后搞砸了什么吗?它是unpythonic吗?为什么这不是

标准操作程序?


rg

解决方案

< blockquote> Ron Garret schrieb:


我发现有关Python的烦恼之一就是当你对方法定义做出改变时该更改未反映在类的现有

实例中(因为当你重新加载类定义而不是实际重新定义它时,你真的定义了一个新类) 。所以我用这种编程风格来了




def defmethod(cls):

return lambda(func):type .__ setattr __(cls,func.func_name,func)

class c1(object):pass


@defmethod(c1)

def m1(self,x):...


现在,如果重新定义m1,现有的c1实例将会看到更改。

我的问题是:有没有理由不这样做?在幕后搞砸了什么吗?它是unpythonic吗?为什么这不是b
标准操作程序?



你在做什么需要这种永久性的重新定义?我喜欢

repl,但通常 - 特别是在处理类时 - 我写了一个包含代码的

文本文件。所以,我再次在命令行上运行它,

如果我做了一些更改,重新创建我想要的任何对象。


即使我'' d不这样做,但在

IDE中使用了一个长期运行的解释器(这是我认为你正在做的事情) - 为什么你_care_关于

旧对象第一名?我的意思是,你明显改变了

类是有原因的。所以,你在这里没有多少工作效率,但仍然是b
编程。这意味着你不要太过关心旧的,


但最后 - 这是你的代码。它会运行得慢一点,它看起来有点儿好看起来很奇怪因为正在阅读它的人必须知道它的用途,但是如果它b / b $ b适合你的需要 - 做它。


Diez


文章< 4t ************* @ mid。 uni-berlin.de>,

" Diez B. Roggisch" < de *** @ nospam.web.dewrote:


Ron Garret schrieb:


One我发现对Python感到讨厌的事情是,当你对一个方法定义做出改变时,改变不会反映在一个类的现有

实例中(因为你'当你重新加载一个类定义而不是实际重新定义它时,确实正在定义一个新类。所以我用这种编程风格来了




def defmethod(cls):

return lambda(func):type .__ setattr __(cls,func.func_name,func)

class c1(object):pass


@defmethod(c1)

def m1(self,x):...

现在,如果重新定义m1,现有的c1实例将看到更改。


我的问题是:有没有理由不这样做?在幕后搞砸了什么吗?它是unpythonic吗?为什么这不是b
标准操作程序?



你在做什么需要这种永久性的重新定义?我喜欢

repl,但通常 - 特别是在处理类时 - 我写了一个包含代码的

文本文件。所以,我再次在命令行上运行它,

如果我做了一些更改,重新创建我想要的任何对象。


即使我'' d不这样做,但在

IDE中使用了一个长期运行的解释器(这是我认为你正在做的事情) - 为什么你_care_关于

旧对象第一名?我的意思是,你明显改变了

类是有原因的。所以,你在这里没有多少工作效率,但仍然是b
编程。这意味着你不要太过关心旧的,


但最后 - 这是你的代码。它会运行得慢一点,它看起来有点儿好看起来很奇怪因为正在阅读它的人必须知道它的用途,但是如果它b / b $ b适合你的需要 - 做它。


Diez



我有两个动机。


首先,我我正在处理一些实例需要花费很长时间才能构建的类,如果我必须在每次代码更改后重新构建
它们,那么这需要很长的调试周期。


其次,设计自然似乎就这样打破了。我有一个库,它为一组现有的

类增加了功能(持久性)。持久性代码将对象存储在关系数据库中,因此

它是非常多毛的代码,它与类实际提供的功能无关
。使用持久性代码,原始类甚至是有用的,并且我正在努力保持轻量级。


如果有更好的方法完成所有这些我很满意。


rg


Ron Garret写道:


文章< 4t ************* @ mid.uni-berlin.de>,

" Diez B. Roggisch" ; < de *** @ nospam.web.dewrote:


Ron Garret schrieb:


One我发现对Python感到讨厌的事情是,当你对一个方法定义做出改变时,改变不会反映在一个类的现有

实例中(因为你'当你重新加载一个类定义而不是实际重新定义它时,确实正在定义一个新类。所以我用这种编程风格来了



>

def defmethod(cls):

返回lambda(func):type .__ setattr __(cls,func.func_name,func)

>

class c1(object):pass

>

@defmethod(c1)

def m1(self,x):...

>

>

现在,如果重新定义m1,现有的c1实例将会看到更改。

>

我的问题是:是有理由不这样做吗?在幕后搞砸了什么吗?它是unpythonic吗?为什么这不是b
标准操作程序?



1.你的意思是,是否有它会使解释器崩溃原因?没有。

2.不适用于大多数普通情况。有一些陷阱(例如,

使用__private变量),但它们很小。

3.是。

4.因为它是unPythonic。


但是如果你偶尔做一些unPythonic的话,不要太担心。

Python说有'应该是一个 - 最好只有一个 - 明显的方式

来做。因此,如果没有明显的方法可以做到这一点,你可能需要

做一些unPythonic。 (或者咨询有经验的人。:)

[snip]


我有两个动机。


首先,我正在处理一些实例需要花费很长时间来构建的类,如果我需要重构
$ b $,这需要很长的调试周期b每次代码更改后都会出现这种情况。


其次,设计自然似乎会以这种方式分解。我有一个库,它为一组现有的

类增加了功能(持久性)。持久性代码将对象存储在关系数据库中,因此

它是非常多毛的代码,它与类实际提供的功能无关
。使用持久性代码,原始类甚至是有用的,并且我正在尝试保持轻量级。



对我来说似乎是一个合理的用例。


如果有更好的方法可以完成所有这些我都是耳朵。



简单的Pythonic方法就是创建一个

中间表示,理解现有的类

接口和RDB的东西,但这可能导致同步
问题和性能大打折扣。与方法相比,它可能需要花费很多工作。 OTOH,它可以帮助你毛茸茸

提到。 (我最近在我的一个项目中做了类似的事情,

虽然中介是暂时的。)


您可能能够创建一组增强子类使用

代替。这个问题的主要问题是基类通常不会对增强版本有所了解。你必须覆盖代码,

需要一个包含允许增强对象的代码的普通对象。

这有时非常不方便(比如代码需要

普通对象是100行中间的一行

函数。)


实际上听起来像面向方面编程可能会有所帮助

这里(如果你想学习另一个完全不同的编程

范例,那就是)。从类的目的来看,你有一个问题(持久性)在另一个维度上是非常好的。

或许最好的方法就是教一个旧班级新招数。

Carl Banks



One of the things I find annoying about Python is that when you make a
change to a method definition that change is not reflected in existing
instances of a class (because you''re really defining a new class when
you reload a class definition, not actually redefining it). So I came
up with this programming style:

def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)

class c1(object): pass

@defmethod(c1)
def m1(self, x): ...
Now if you redefine m1, existing instances of c1 will see the change.

My question is: is there a reason not to do this? Does it screw
something up behind the scenes? Is it unpythonic? Why isn''t this
standard operating procedure?

rg

解决方案

Ron Garret schrieb:

One of the things I find annoying about Python is that when you make a
change to a method definition that change is not reflected in existing
instances of a class (because you''re really defining a new class when
you reload a class definition, not actually redefining it). So I came
up with this programming style:

def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)

class c1(object): pass

@defmethod(c1)
def m1(self, x): ...
Now if you redefine m1, existing instances of c1 will see the change.

My question is: is there a reason not to do this? Does it screw
something up behind the scenes? Is it unpythonic? Why isn''t this
standard operating procedure?

What are you doing that needs this permanent redefinition? I like the
repl, yet usually - especially when dealing with classes - I write a
text file containing code. So, i just run that on a command line again,
if I made some changes, recreating whatever objects I want again.

Even if I''d not do that, but used a long-running interpreter inside an
IDE (which is what I presume you are doing) - why do you _care_ about
the old objects the first place? I mean, you obviously changed the
classes for a reason. So, you are not being productive here, but still
programming. Which means that you don''t _have_ to care about old,
unchanged objects too much.

But in the end - it''s your code. It will run slower, it looks kinda
weird as someone who''s reading it has to know what it is for, but if it
suits your needs - do it.

Diez


In article <4t*************@mid.uni-berlin.de>,
"Diez B. Roggisch" <de***@nospam.web.dewrote:

Ron Garret schrieb:

One of the things I find annoying about Python is that when you make a
change to a method definition that change is not reflected in existing
instances of a class (because you''re really defining a new class when
you reload a class definition, not actually redefining it). So I came
up with this programming style:

def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)

class c1(object): pass

@defmethod(c1)
def m1(self, x): ...
Now if you redefine m1, existing instances of c1 will see the change.

My question is: is there a reason not to do this? Does it screw
something up behind the scenes? Is it unpythonic? Why isn''t this
standard operating procedure?


What are you doing that needs this permanent redefinition? I like the
repl, yet usually - especially when dealing with classes - I write a
text file containing code. So, i just run that on a command line again,
if I made some changes, recreating whatever objects I want again.

Even if I''d not do that, but used a long-running interpreter inside an
IDE (which is what I presume you are doing) - why do you _care_ about
the old objects the first place? I mean, you obviously changed the
classes for a reason. So, you are not being productive here, but still
programming. Which means that you don''t _have_ to care about old,
unchanged objects too much.

But in the end - it''s your code. It will run slower, it looks kinda
weird as someone who''s reading it has to know what it is for, but if it
suits your needs - do it.

Diez

I have two motivations.

First, I''m dealing with some classes whose instances take a long time to
construct, which makes for a long debug cycle if I have to reconstruct
them after every code change.

Second, the design just naturally seems to break down that way. I have
a library that adds functionality (persistence) to a set of existing
classes. The persistence code stores the objects in a relational DB, so
it''s pretty hairy code, and it has nothing to do with the functionality
that the classes actually provide. The original classes are useful even
with the persistence code, and I''m trying to keep things lightweight.

If there''s a better way to accomplish all this I''m all ears.

rg


Ron Garret wrote:

In article <4t*************@mid.uni-berlin.de>,
"Diez B. Roggisch" <de***@nospam.web.dewrote:

Ron Garret schrieb:

One of the things I find annoying about Python is that when you make a
change to a method definition that change is not reflected in existing
instances of a class (because you''re really defining a new class when
you reload a class definition, not actually redefining it). So I came
up with this programming style:
>
def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)
>
class c1(object): pass
>
@defmethod(c1)
def m1(self, x): ...
>
>
Now if you redefine m1, existing instances of c1 will see the change.
>
My question is: is there a reason not to do this? Does it screw
something up behind the scenes? Is it unpythonic? Why isn''t this
standard operating procedure?

1. Do you mean, is there an "it''ll crash the interpreter" reason? No.
2. Not for most ordinary cases. There are a few gotchas (for example,
use of __private variables), but they''re minor.
3. Yes.
4. Because it''s unPythonic.

But don''t worry too much if you do something unPythonic occasionally.
Python says there''s should be one--and preferably only one--obvious way
to do it. So if there''s no obvious way to do it, you probably have to
do something unPythonic. (Or consult someone with more experience. :)
[snip]

I have two motivations.

First, I''m dealing with some classes whose instances take a long time to
construct, which makes for a long debug cycle if I have to reconstruct
them after every code change.

Second, the design just naturally seems to break down that way. I have
a library that adds functionality (persistence) to a set of existing
classes. The persistence code stores the objects in a relational DB, so
it''s pretty hairy code, and it has nothing to do with the functionality
that the classes actually provide. The original classes are useful even
with the persistence code, and I''m trying to keep things lightweight.

Seems like a reasonable use case to me.

If there''s a better way to accomplish all this I''m all ears.

A straightforward, Pythonic way to do it would be to create an
intermediate representation that understands both the existing class
interfaces and the RDB stuff, but that could lead to synchronizing
problems and a big hit in performance. And it''s probably a lot of work
compared to tacking on methods. OTOH, it could help with hairiness you
mention. (I recently did something similar in one of my projects,
though the intermediary was transient.)

You might be able to create a set of augmented subclasses to use
instead. The main problem with this is that base classes often don''t
know about the augmented versions. You''d have to override code that
requires an ordinary object with code that allows an augmented object.
This is sometimes very inconvenient (like when the code requiring an
ordinary object is one line smack in the middle of a 100-line
function).

It actually sounds like Aspect Oriented Programming might be helpful
here (if you care to learn another wholly different programming
paradigm, that is). You have a concern (persistence) that''s pretty
much off in another dimension from the purpose of the classes.
Or maybe the best way is just to teach an old class new tricks.
Carl Banks


这篇关于有没有理由不这样做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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