使用“私人”参数为静态存储? [英] using "private" parameters as static storage?

查看:59
本文介绍了使用“私人”参数为静态存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从REALbasic迁移到Python时,我想念的一件事就是能够在一个方法中拥有静态存储空间 - 即存储是持久的

来电,但在方法之外不可见。我经常使用

这样的东西用于缓存,或用于跟踪工厂函数创建了多少

个对象,等等。


今天我发现使用一个可变对象作为参数的默认值

。一个简单的例子:


def spam(_count = [0]):

_count [0] + = 1

返回垃圾邮件 * _count [0]


>> spam()



''垃圾邮件''


>> spam()



''垃圾邮件''


这似乎工作正常,但感觉有点不干净,在方法签名中只有内部使用的东西是
。命名

带有下划线_count的参数让我感觉有点好点/ b $ b更好。但是,添加到模块名称空间

只是供一个函数使用的东西似乎也不干净。


你对这个成语有什么看法?还有另一种解决方案

人们通常更喜欢吗?


哦,为了改变我还有另一个想法,而不是发送相当于

比后。这是另一个技巧:


def spam2():

如果不是hasattr(spam2,''count''):spam2.count = 0

spam2.count + = 1

return" spam2" * spam2.count


这根本不会暴露函数之外的任何不洁。

缺点是函数的名称必须出现几个

次本身,所以如果我重命名这个函数,我必须记住

来改变那些引用。但是,如果我重命名一个函数,

无论如何我都要改变所有的调用者。所以也许这更好。

你们都在想什么?


Best,

- Joe

解决方案

11月13日上午9:16 *,Joe Strout< j ... @ strout.netwrote:


我从REALbasic迁移到Python的一件事是能够*

在方法中有静态存储 - 即存储是持久的*
$ b调用之间的$ b,但在方法之外不可见。 *我经常使用*

这些用于缓存,或跟踪工厂函数创建的对象数量*

等等。


今天我发现使用一个可变对象作为参数的默认值*

。 *一个简单的例子:


def spam(_count = [0]):

* * * _count [0] + = 1

* * *返回垃圾邮件 * _count [0]


*>>垃圾邮件()

''垃圾邮件''

*>> ;垃圾邮件()

''垃圾邮件''



不要这样做,这是令人困惑的,肯定有(很多) )更好

python中用于处理已保存状态的设施。


哦,为了改变我还有另一个想法,然后点击发送相反*

比之后。 *这是另一招:


def spam2():

* * *如果不是hasattr(spam2,''count''):spam2 .count = 0

* * * spam2.count + = 1

* * * return" spam2" * spam2.count



这绝对比第一个更受欢迎。然而,首选的

方法只是使用一个类。保留状态是什么类

for。


> >类垃圾邮件(对象):



.... def __init __(self):

.... self._count = 0

.... def spam(self):

.... self._count + = 1

....返回 " ;.join(&x)for xrange中的垃圾邮件(self._count))

....


>> x =垃圾邮件()
打印x.spam()



垃圾邮件


>> print x.spam()



垃圾邮件


>> print x.spam()



垃圾邮件垃圾邮件


它还使您能够在同一个状态机中拥有两个完全独立的

实例。


>> y =垃圾邮件()
打印y.spam()



垃圾邮件


>>打印y.spam()



垃圾邮件

< blockquote class =post_quotes>


>> print y.spam()



垃圾邮件垃圾邮件


>>>



如果您需要方便或

向后兼容性,您可以像功能一样使用它:


>> spam =垃圾邮件()。垃圾邮件
打印垃圾邮件( )



spam


>>打印垃圾邮件()



垃圾邮件垃圾邮件


>> print spam()



垃圾邮件垃圾邮件


或者:


>>类垃圾邮件(对象):



.... def __init __(自我):

.... self._count = 0

....

.... def spam(self):

.... self._count + = 1

.... return" " .join(&x)for xrange中的垃圾邮件(self._count))

....

.... __ call__ =垃圾邮件

....


>> spam = Spam()
print spam()



spam


>> print spam()



垃圾邮件


>> print spam()



垃圾邮件垃圾邮件

Matt


On Thu,2008-11-13 at 09: 38 -0800,Matimus写道:


11月13日上午9:16,Joe Strout< j ... @ strout.netwrote:
< blockquote class =post_quote s>
当我从REALbasic转向Python时,我想念的一件事就是能够在一个方法中使用静态存储来获得静态存储 - 即存储是持久的

之间的调用,但在方法之外不可见。我经常使用

这样的东西用于缓存,或用于跟踪工厂函数创建了多少

个对象,等等。


今天我发现使用一个可变对象作为参数的默认值

。一个简单的例子:


def spam(_count = [0]):

_count [0] + = 1

返回垃圾邮件 * _count [0]


>> spam()



''spam''


>> spam()



''垃圾邮件''



不要这样做,这是令人困惑的,并且在python中有一定的(很多)更好的

设施来处理已保存的状态。


哦,对于一个改变,我有另一个想法,然后点击发送而不是之后的b $ b。这是另一个技巧:


def spam2():

如果不是hasattr(spam2,''count''):spam2.count = 0

spam2.count + = 1

return" spam2" * spam2.count




这绝对比第一个更受欢迎。然而,首选的

方法只是使用一个类。保留状态是什么类

for。



保存状态是*对象*的用途。甚至内置函数都要保留

状态(例如,列表.__ len __,func.func_code)。


类用于创建自定义对象。 />


> class Spam(object):



... def __init __(self):

... self._count = 0

... def spam(self):

... self._count + = 1

... return" " .join(x中的_垃圾邮件(self._count))

...



哦当然。这是一个更清晰的方式来返回响应,而不是我使用的那个。 (仅供参考,我使用:`return(" spam" * self._count).rstrip()`

我甚至不喜欢rstrip .Dunno为什么我没想到它。


>类垃圾邮件(对象):



... def __init __(自我):

。 .. self._count = 0

...

... def spam(self):

... self._count + = 1

...返回 " ;.join(&x)for xrange中的垃圾邮件(self._count))

...

... __call__ =垃圾邮件

...



有趣。我没想过让__call__成为

现有方法的同义词。我想我喜欢那样,但我不太确定。有一些东西让我觉得有两种方法可以做同样的事情,

但我喜欢给这个方法一个比__call __更具描述性的名字。


欢呼,

Cliff


11月13日上午11:32,J。 Cliff Dyer < j ... @sdf.lonestar.orgwrote:


On Thu,2008-11-13 at 09:38 -0800,Matimus写道:


11月13日上午9:16,Joe Strout< j ... @ strout.netwrote:


当我从REALbasic迁移到Python时,我想念的一件事就是能够在一个方法中拥有静态存储空间 - 即存储是持久的

之间的呼叫,但不是在方法之外可见。我经常使用

这样的东西用于缓存,或用于跟踪工厂函数创建了多少

个对象,等等。


今天我发现使用可变对象作为默认值

参数。一个简单的例子:


def spam(_count = [0]):

_count [0] + = 1

返回垃圾邮件 * _count [0]


>> spam()

''垃圾邮件''

>>垃圾邮件()

''垃圾邮件''


不要这样做,这是令人困惑的,并且在python中有一定的(很多)更好的
设施来处理已保存的状态。


哦,对于一个改变我有另一个想法,然后点击发送而不是
比后。这是另一个技巧:


def spam2():

如果不是hasattr(spam2,''count''):spam2.count = 0

spam2.count + = 1

return" spam2" * spam2.count


这绝对比第一个更受欢迎。然而,首选的

方法只是使用一个类。保留状态是什么类

for。



保存状态是*对象*的用途。



不仅仅是,发电机也保留状态。


def _spam():

count = 1

而1:

收益率垃圾邮件 *计数

count + = 1

spam = _spam.next()


One thing I miss as I move from REALbasic to Python is the ability to
have static storage within a method -- i.e. storage that is persistent
between calls, but not visible outside the method. I frequently use
this for such things as caching, or for keeping track of how many
objects a factory function has created, and so on.

Today it occurred to me to use a mutable object as the default value
of a parameter. A simple example:

def spam(_count=[0]):
_count[0] += 1
return "spam " * _count[0]

>>spam()

''spam ''

>>spam()

''spam spam ''

This appears to work fine, but it feels a little unclean, having stuff
in the method signature that is only meant for internal use. Naming
the parameter with an underscore "_count" makes me feel a little
better about it. But then, adding something to the module namespace
just for use by one function seems unclean too.

What are your opinions on this idiom? Is there another solution
people generally prefer?

Ooh, for a change I had another thought BEFORE hitting Send rather
than after. Here''s another trick:

def spam2():
if not hasattr(spam2,''count''):spam2.count=0
spam2.count += 1
return "spam2 " * spam2.count

This doesn''t expose any uncleanliness outside the function at all.
The drawback is that the name of the function has to appear several
times within itself, so if I rename the function, I have to remember
to change those references too. But then, if I renamed a function,
I''d have to change all the callers anyway. So maybe this is better.
What do y''all think?

Best,
- Joe

解决方案

On Nov 13, 9:16*am, Joe Strout <j...@strout.netwrote:

One thing I miss as I move from REALbasic to Python is the ability to *
have static storage within a method -- i.e. storage that is persistent *
between calls, but not visible outside the method. *I frequently use *
this for such things as caching, or for keeping track of how many *
objects a factory function has created, and so on.

Today it occurred to me to use a mutable object as the default value *
of a parameter. *A simple example:

def spam(_count=[0]):
* * * _count[0] += 1
* * * return "spam " * _count[0]

*>>spam()
''spam ''
*>>spam()
''spam spam ''

Don''t Do this, it is confusing and there are definitely (many) better
facilities in python for handling saved state.

Ooh, for a change I had another thought BEFORE hitting Send rather *
than after. *Here''s another trick:

def spam2():
* * * if not hasattr(spam2,''count''):spam2.count=0
* * * spam2.count += 1
* * * return "spam2 " * spam2.count


This is definitely preferred over the first. However the preferred
method is just to use a class. Preserving state is what classes are
for.

>>class Spam(object):

.... def __init__(self):
.... self._count = 0
.... def spam(self):
.... self._count += 1
.... return " ".join("spam" for _ in xrange(self._count))
....

>>x = Spam()
print x.spam()

spam

>>print x.spam()

spam spam

>>print x.spam()

spam spam spam

It also gives you the ability to have two compleately separate
instances of the same state machine.

>>y = Spam()
print y.spam()

spam

>>print y.spam()

spam spam

>>print y.spam()

spam spam spam

>>>

You can use it like a function if you need to for convenience or
backwards compatibility.:

>>spam = Spam().spam
print spam()

spam

>>print spam()

spam spam

>>print spam()

spam spam spam

Or:

>>class Spam(object):

.... def __init__(self):
.... self._count = 0
....
.... def spam(self):
.... self._count += 1
.... return " ".join("spam" for _ in xrange(self._count))
....
.... __call__ = spam
....

>>spam = Spam()
print spam()

spam

>>print spam()

spam spam

>>print spam()

spam spam spam
Matt


On Thu, 2008-11-13 at 09:38 -0800, Matimus wrote:

On Nov 13, 9:16 am, Joe Strout <j...@strout.netwrote:

One thing I miss as I move from REALbasic to Python is the ability to
have static storage within a method -- i.e. storage that is persistent
between calls, but not visible outside the method. I frequently use
this for such things as caching, or for keeping track of how many
objects a factory function has created, and so on.

Today it occurred to me to use a mutable object as the default value
of a parameter. A simple example:

def spam(_count=[0]):
_count[0] += 1
return "spam " * _count[0]

>>spam()

''spam ''

>>spam()

''spam spam ''


Don''t Do this, it is confusing and there are definitely (many) better
facilities in python for handling saved state.

Ooh, for a change I had another thought BEFORE hitting Send rather
than after. Here''s another trick:

def spam2():
if not hasattr(spam2,''count''):spam2.count=0
spam2.count += 1
return "spam2 " * spam2.count



This is definitely preferred over the first. However the preferred
method is just to use a class. Preserving state is what classes are
for.

Preserving state is what *objects* are for. Even the builtins have
state to be preserved (list.__len__, func.func_code, for example).

Classes are for creating custom objects.

>class Spam(object):

... def __init__(self):
... self._count = 0
... def spam(self):
... self._count += 1
... return " ".join("spam" for _ in xrange(self._count))
...

Oh of course. This is a much cleaner way to return the response than
the one I used. (FYI, I used: `return ("spam " * self._count).rstrip()`
and I didn''t like the rstrip even when I was doing it. Dunno why I
didn''t think of it.)

>class Spam(object):

... def __init__(self):
... self._count = 0
...
... def spam(self):
... self._count += 1
... return " ".join("spam" for _ in xrange(self._count))
...
... __call__ = spam
...

Interesting. I hadn''t thought of making __call__ a synonym for an
existing method. I think I like that, but I''m not quite sure. There''s
something that nags at me about having two ways to do the same thing,
but I like giving the method a more descriptive name than __call__.

Cheers,
Cliff


On Nov 13, 11:32 am, "J. Cliff Dyer" <j...@sdf.lonestar.orgwrote:

On Thu, 2008-11-13 at 09:38 -0800, Matimus wrote:

On Nov 13, 9:16 am, Joe Strout <j...@strout.netwrote:

One thing I miss as I move from REALbasic to Python is the ability to
have static storage within a method -- i.e. storage that is persistent
between calls, but not visible outside the method. I frequently use
this for such things as caching, or for keeping track of how many
objects a factory function has created, and so on.

Today it occurred to me to use a mutable object as the default value
of a parameter. A simple example:

def spam(_count=[0]):
_count[0] += 1
return "spam " * _count[0]

>>spam()
''spam ''
>>spam()
''spam spam ''

Don''t Do this, it is confusing and there are definitely (many) better
facilities in python for handling saved state.

Ooh, for a change I had another thought BEFORE hitting Send rather
than after. Here''s another trick:

def spam2():
if not hasattr(spam2,''count''):spam2.count=0
spam2.count += 1
return "spam2 " * spam2.count

This is definitely preferred over the first. However the preferred
method is just to use a class. Preserving state is what classes are
for.


Preserving state is what *objects* are for.

Not exclusively, generators also preserve state.

def _spam():
count = 1
while 1:
yield "spam " * count
count += 1
spam = _spam.next()


这篇关于使用“私人”参数为静态存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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