本文介绍了使用“私人”参数为静态存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 当我从REALbasic迁移到Python时,我想念的一件事就是能够在一个方法中拥有静态存储空间 - 即存储是持久的 来电,但在方法之外不可见。我经常使用 这样的东西用于缓存,或用于跟踪工厂函数创建了多少 个对象,等等。 今天我发现使用一个可变对象作为参数的默认值 。一个简单的例子: def spam(_count = [0]): _count [0] + = 1 返回垃圾邮件 * _count [0] ''垃圾邮件'' ''垃圾邮件'' 这似乎工作正常,但感觉有点不干净,在方法签名中只有内部使用的东西是。命名 带有下划线_count的参数让我感觉有点好点/ b $ b更好。但是,添加到模块名称空间 只是供一个函数使用的东西似乎也不干净。 你对这个成语有什么看法?还有另一种解决方案 人们通常更喜欢吗? 哦,为了改变我还有另一个想法,而不是发送相当于 比后。这是另一个技巧: def spam2(): 如果不是hasattr(spam2,''count''):spam2.count = 0 spam2.count + = 1 return" spam2" * spam2.count 这根本不会暴露函数之外的任何不洁。 缺点是函数的名称必须出现几个 次本身,所以如果我重命名这个函数,我必须记住 来改变那些引用。但是,如果我重命名一个函数, 无论如何我都要改变所有的调用者。所以也许这更好。 你们都在想什么? Best, - Joe 解决方案 不要这样做,这是令人困惑的,肯定有(很多) )更好 python中用于处理已保存状态的设施。 这绝对比第一个更受欢迎。然而,首选的 方法只是使用一个类。保留状态是什么类 for。 .... def __init __(self): .... self._count = 0 .... def spam(self): .... self._count + = 1 ....返回 " ;.join(&x)for xrange中的垃圾邮件(self._count)) .... 垃圾邮件 垃圾邮件 垃圾邮件垃圾邮件 它还使您能够在同一个状态机中拥有两个完全独立的 实例。 垃圾邮件 垃圾邮件 垃圾邮件垃圾邮件 如果您需要方便或 向后兼容性,您可以像功能一样使用它: spam 垃圾邮件垃圾邮件 垃圾邮件垃圾邮件 或者: .... def __init __(自我): .... self._count = 0 .... .... def spam(self): .... self._count + = 1 .... return" " .join(&x)for xrange中的垃圾邮件(self._count)) .... .... __ call__ =垃圾邮件 .... spam 垃圾邮件 垃圾邮件垃圾邮件 Matt ''spam'' ''垃圾邮件'' 不要这样做,这是令人困惑的,并且在python中有一定的(很多)更好的 设施来处理已保存的状态。 这绝对比第一个更受欢迎。然而,首选的 方法只是使用一个类。保留状态是什么类 for。 保存状态是*对象*的用途。甚至内置函数都要保留 状态(例如,列表.__ len __,func.func_code)。 类用于创建自定义对象。 /> ... 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 保存状态是*对象*的用途。 不仅仅是,发电机也保留状态。 def _spam(): count = 1 而1: 收益率垃圾邮件 *计数 count + = 1 spam = _spam.next() One thing I miss as I move from REALbasic to Python is the ability tohave static storage within a method -- i.e. storage that is persistentbetween calls, but not visible outside the method. I frequently usethis for such things as caching, or for keeping track of how manyobjects a factory function has created, and so on. Today it occurred to me to use a mutable object as the default valueof a parameter. A simple example: def spam(_count=[0]):_count[0] += 1return "spam " * _count[0] ''spam '' ''spam spam '' This appears to work fine, but it feels a little unclean, having stuffin the method signature that is only meant for internal use. Namingthe parameter with an underscore "_count" makes me feel a littlebetter about it. But then, adding something to the module namespacejust for use by one function seems unclean too. What are your opinions on this idiom? Is there another solutionpeople generally prefer? Ooh, for a change I had another thought BEFORE hitting Send ratherthan after. Here''s another trick: def spam2():if not hasattr(spam2,''count''):spam2.count=0spam2.count += 1return "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 severaltimes within itself, so if I rename the function, I have to rememberto 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 解决方案 Don''t Do this, it is confusing and there are definitely (many) betterfacilities in python for handling saved state. This is definitely preferred over the first. However the preferredmethod is just to use a class. Preserving state is what classes arefor. .... def __init__(self):.... self._count = 0.... def spam(self):.... self._count += 1.... return " ".join("spam" for _ in xrange(self._count)).... spam spam spam spam spam spam It also gives you the ability to have two compleately separateinstances of the same state machine. spam spam spam spam spam spam You can use it like a function if you need to for convenience orbackwards compatibility.: spam spam spam spam spam spam Or: .... def __init__(self):.... self._count = 0........ def spam(self):.... self._count += 1.... return " ".join("spam" for _ in xrange(self._count))........ __call__ = spam.... spam spam spam spam spam spamMatt ''spam '' ''spam spam '' Don''t Do this, it is confusing and there are definitely (many) betterfacilities in python for handling saved state. This is definitely preferred over the first. However the preferredmethod is just to use a class. Preserving state is what classes arefor. Preserving state is what *objects* are for. Even the builtins havestate to be preserved (list.__len__, func.func_code, for example). Classes are for creating custom objects. ... 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 thanthe 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 Ididn''t think of it.) ... 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 anexisting method. I think I like that, but I''m not quite sure. There''ssomething 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 Preserving state is what *objects* are for.Not exclusively, generators also preserve state. def _spam():count = 1while 1:yield "spam " * countcount += 1spam = _spam.next() 这篇关于使用“私人”参数为静态存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-28 06:23