Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the pythonic way of declaring variables?

Tags:

python

Usually declaring variables on assignment is considered a best practice in VBScript or JavaScript , for example, although it is allowed.

Why does Python force you to create the variable only when you use it? Since Python is case sensitive can't it cause bugs because you misspelled a variable's name?

How would you avoid such a situation?

like image 724
the_drow Avatar asked Feb 06 '10 15:02

the_drow


People also ask

How many ways can you declare a variable in Python?

Numbers. Python supports three types of numbers - integer, floating point numbers, and complex. We can declare a variable with any length, there is no restriction declares any length of the variable.

What is the correct way to declare a variable in Python?

Python has no command for declaring a variable. A variable is created the moment you first assign a value to it.

What is the correct way of declaring a variable?

To declare (create) a variable, you will specify the type, leave at least one space, then the name for the variable and end the line with a semicolon ( ; ). Java uses the keyword int for integer, double for a floating point number (a double precision number), and boolean for a Boolean value (true or false).


3 Answers

If you do any serious development you'll use a (integrated) development environment. Pylint will be part of it and tell you all your misspellings. No need to make such a feature part of the langauge.

like image 200
Jochen Ritzel Avatar answered Sep 27 '22 00:09

Jochen Ritzel


It's a silly artifact of Python's inspiration by "teaching languages", and it serves to make the language more accessible by removing the stumbling block of "declaration" entirely. For whatever reason (probably represented as "simplicity"), Python never gained an optional stricture like VB's "Option Explicit" to introduce mandatory declarations. Yes, it can be a source of bugs, but as the other answers here demonstrate, good coders can develop habits that allow them to compensate for pretty much any shortcoming in the language -- and as shortcomings go, this is a pretty minor one.

like image 21
hobbs Avatar answered Sep 27 '22 00:09

hobbs


If you want a class with "locked-down" instance attributes, it's not hard to make one, e.g.:

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()

As you'll see, the calls to x.onemore work just fine, but reset raises an exception because of the mis-spelling of the attribute as mitsakes. The rules of engagement here are that __init__ must set all attributes to initial values, then call self._dolock() to forbid any further addition of attributes. I'm exempting "super-private" attributes (ones starting with __), which stylistically should be used very rarely, for totally specific roles, and with extremely limited scope (making it trivial to spot typos in the super-careful inspection that's needed anyway to confirm the need for super-privacy), but that's a stylistic choice, easy to reverse; similarly for the choice to make the locked-down state "irreversible" (by "normal" means -- i.e. requiring very explicit workaround to bypass).

This doesn't apply to other kinds of names, such as function-local ones; again, no big deal because each function should be very small, and is a totally self-contained scope, trivially easy to inspect (if you write 100-lines functions, you have other, serious problems;-).

Is this worth the bother? No, because semi-decent unit tests should obviously catch all such typos with the greatest of ease, as a natural side effect of thoroughly exercising the class's functionality. In other words, it's not as if you need to have more unit tests just to catch the typos: the unit tests you need anyway to catch trivial semantic errors (off-by-one, +1 where -1 is meant, etc., etc.) will already catch all typos, too.

Robert Martin and Bruce Eckel both articulated this point 7 years ago in separate and independent articles -- Eckel's blog is temporarily down right now, but Martin's right here, and when Eckel's site revives the article should be here. The thesis is controversial (Jeff Attwood and his commenters debate it here, for example), but it's interesting to note that Martin and Eckel are both well-known experts of static languages such as C++ and Java (albeit with love affairs, respectively, with Ruby and Python), and they're far from the only ones to have discovered the importance of unit-tests... and how a good unit-tests suite, as a side effect, makes a static language's rigidity redundant.

By the way, one way to check your test suites is "error injection": systematically go over your codebase introducing one mis-spelling -- run the tests to make sure they do fail, if they don't add one that does fail, correct the spelling mistake, repeat. Can be fairly well automated (not the "add a test" part, but the finding of potential errors that aren't covered by the suite), as can some other forms of error injections (change every integer constant, one by one, to one more, and to one less; change each < to <= etc; swap each if and while condition to its reverse; ...), while other forms of error-injection yet require a lot more human savvy. Unfortunately I don't know of publicly available suites of error injection frameworks (for any language) -- might make a cool open source project;-).

like image 29
Alex Martelli Avatar answered Sep 23 '22 00:09

Alex Martelli