什么是声明变量的pythonic方式?

the*_*row 10 python

通常在赋值时声明变量被认为是VBScript或JavaScript中的最佳实践,例如,虽然它是允许的.

为什么Python强制您仅在使用它时创建变量?由于Python区分大小写不能导致错误,因为你错误拼写了一个变量的名字?

你会如何避免这种情况?

hob*_*bbs 15

这是"教学语言"对Python灵感的愚蠢神器,它通过完全消除"声明"的绊脚石,使语言更易于访问.无论出于何种原因(可能表示为"简单"),Python从未获得像VB的"Option Explicit"这样的可选限制来引入强制声明.是的,它可能是错误的来源,但正如其他答案所示,良好的程序员可以养成习惯,使他们能够弥补语言中的任何缺点 - 而且由于缺点,这是一个非常小的问题.

  • 我希望这个答案获胜.很明显,答案是"你不能用Python做到这一点,但它不像你想象的那么重要." (3认同)

Ale*_*lli 12

如果你想要一个具有"锁定"实例属性的类,那么制作一个类并不难,例如:

class LockedDown(object):
  __locked = False
  def __setattr__(self, name, value):
    if self.__locked:
      if name[:2] != '__' and name not in self.__dict__:
        raise ValueError("Can't set attribute %r" % name)
    object.__setattr__(self, name, value)
  def _dolock(self):
    self.__locked = True

class Example(LockedDown):
  def __init__(self):
    self.mistakes = 0
    self._dolock()
  def onemore(self):
    self.mistakes += 1
    print self.mistakes
  def reset(self):
    self.mitsakes = 0

x = Example()
for i in range(3): x.onemore()
x.reset()
Run Code Online (Sandbox Code Playgroud)

正如您将看到的那样,调用x.onemore工作正常,但reset由于属性拼写错误而引发异常mitsakes.这里的参与规则是__init__必须将所有属性设置为初始值,然后调用self._dolock()禁止任何进一步添加属性.我正在豁免"超级私人"属性(开头的__),风格应该很少使用,完全具体的角色,并且范围极其有限(无论如何都要在超级仔细的检查中发现拼写错误确认是否需要超级隐私),但这是一种风格选择,容易扭转; 类似地,选择使锁定状态"不可逆"(通过"正常"意味着 - 即需要非常明确的解决方法来绕过).

这不适用于其他类型的名称,例如函数本地名称; 再次,没什么大不了的,因为每个函数都应该非常小,并且是一个完全独立的范围,很容易检查(如果你编写100行函数,你还有其他严重的问题;-).

这值得打扰吗?不,因为半体面的单元测试显然应该最容易地捕获所有这样的拼写错误,作为彻底运用该类功能的自然副作用.换句话说,这并不是说你需要进行更多的单元测试来捕获拼写错误:无论如何你需要的单元测试来捕捉琐碎的语义错误(逐个,+1表示-1,等等,等等)也会抓住所有错别字.

7年前罗伯特·马丁和布鲁斯·埃克尔在单独和独立的文章中都阐述了这一点 - 埃克尔的博客现在暂时停止了,但马丁就在这里,当埃克尔的网站重新发表文章应该​​在这里.这篇论文是有争议的(例如,Jeff Attwood及其评论者在这里进行辩论),但有趣的是,Martin和Eckel都是C++和Java等静态语言的知名专家(尽管分别是爱情事务, Ruby和Python),他们远远不是唯一发现单元测试重要性的人......以及一个好的单元测试套件作为副作用如何使静态语言的刚性变得多余.

顺便说一句,一个方法来检查你的测试套件是"错误注射":系统地复习你的代码中引入一个错误的拼写-运行测试,以确保它们都失败了,如果他们不添加一个失败,纠正拼写错误,重复一遍.可以相当好地自动化(不是"添加测试"部分,而是查找套件未涵盖的潜在错误),以及一些其他形式的错误注入(将每个整数常量逐个更改为还有一个,少一个;把每个<改为<=等;交换每个ifwhile条件到它的反向; ...),而其他形式的错误注入需要更多的人类悟性.不幸的是,我不知道公开可用的错误注入框架套件(对于任何语言) - 可能会成为一个很酷的开源项目;-).


dan*_*ben 9

在python中,有必要考虑将变量声明为名称的绑定值.

尽量不要拼错它们,否则你会有新的错误(假设你正在谈论赋值语句 - 引用它们会引起异常).

如果您正在谈论实例变量,那么之后您将无法使用它们.

例如,如果您有一个类myclass并且在其__init__方法中写入self.myvar = 0,那么尝试引用self.myvare将导致错误,而不是给您一个默认值.

  • +1你说的拼写错误让我笑了 (4认同)

Ign*_*ams 5

Python永远不会强迫您仅在使用它时创建变量.您始终可以绑定None到名称,然后在其他地方使用该名称.

  • -1来自我,因为我不认为你真的回答了这个问题.如果您编辑以显示这可以如何防止OP担心的问题,我将+2. (3认同)