What are some characteristics of Python that makes it unique as its own language? I'm looking for any sort of characteristics ranging from good to bad, useful to hindrance, syntax to real-world usage, but non-obscure observations would be the most useful for the average developer.

I'm a newb here, so intuitive things may need to be explained.....

  • 9
    Python is not unique, it does not contain a single unique feature not seen in any other language. – SK-logic Dec 30 '11 at 8:59
  • 10
    It's the only language I know that's named after Monty Python... – yannis Dec 30 '11 at 12:25
  • @SK-logic the question is about characteristics, of which features are a subset. Are there no characteristics unique to Python? – kojiro Dec 30 '11 at 13:48
  • @kojiro, I've never seen a formal definition of a "characteristic", so I'd prefer not to guess. – SK-logic Dec 30 '11 at 14:18
  • 1
    @kojiro, PL features are normally understood as both its syntax and semantics. And both are formally defined. – SK-logic Dec 30 '11 at 15:13

You'll have a hard time finding features which are absolutely unique. Most language features in existence have been adopted in more than one language since their inception. Some may be rarer, mostly because they're either new and still in obscurity, or died out for good reason. Nevertheless, even then you'd be better off looking at combinations of features.

That said, several features of Python should make for a relatively unique combination. At least I'm not aware of any languages remotely as popular (and practical) with a mostly overlapping feature set. As noted in comments, Ruby is pretty close, but there are nevertheless numerous differences.

  • Metaclass-based metaprogramming. Basically, running arbitary code on class creation. Makes for very nice class customization with very little work on the recieving end - e.g. for an Object-relational Mapping (ORM), client classes can be written as usual with a few extra lines like attr = SomeDataType() and a ton of code is generated automatically. An example of this are Django's "models".
  • You're encouraged to use iterators for everything. This is especially apparent in 3.x, where most list-based alternatives with an iterator-based equivalent have been abolished in favour of the latter. Iterators also serve as nigh-universal interface for collections (both those you actually have in memory and those you only need once and thus create with the features below). Collection-agnostic, space-efficent (O(1) space for intermediate results often follows naturally, very few tasks actually need all items in memory at once), composable data crunching has never been easier.
  • Generator expressions, related to the above. Many will have heard of list comprehensions (creating a list from another iterable, filtering and mapping in the process, with very convenient syntax). Forget about them, they're syntactic sugar, a special case. Generator expressions are very close in syntactically and ultimately result in the very same sequence of items, but they produce results lazily (and thus take O(1) space unless you explicitly keep the results around).
  • yield, which mainly make writing iterators (called generators here) far nicer. They're the big brother of the above, supporting all kinds of control flow. C# has something similar, with the same keyword. But yield is also overloaded to support a limited kind of coroutines (Lua for instance has more elaborate support) which has nevertheless been put to good use by clever people working on hard problems. Two examples off the top of my head: Recursive descent parsing with backtracing and no stack limit and asynchronous I/O (with convenient syntax).
  • Multi-target assignment and iterable unpacking. Assignment on steroids. Not only you can assign to multiple values at once (even for swapping values and when iterating - for key, value in mapping.items()), you can unpack any iterable of known length (honestly, mostly tuples) into multiple variables. Since 3.x it's even practical for collections of unknown length as you can specify a few variables taking single items and one taking whatever remains: first, *everything_in_between, last = values.
  • Descriptors, probably the most powerful among the various ways to customize attribute access. There are properties (as in C#, but without special language support), static methods, class methods, etc. all implemented as descriptors. They're first-class objects as well. Just a week ago, I've been faced with repetive and tricky code in properties - so I wrote a small function generating the repetive part and wrapping it up in a propery object.
  • Purely offside rule (indentaion for delimiting blocks). I put this last intentionally. While it does distinguish Python, it doesn't really stand out in everyday programming once you're used to it (or at least that's my experience).
| improve this answer | |
  • I'm still a little newb at Ruby but I think hits all but the last point as well? Either way I agree "unique" probably won't be found in Python but "not common amongst other top languages" can be. – Rig Dec 30 '11 at 14:12
  • @Rig: I'm not a Ruby expert, but I've seen neither metaclasses (Ruby's certainly just as powerful regarding metaprogramming, and may use it to similar ends, but my impression was that it's achieved differently), nor generators nor generator expressions (though there seem to be coroutines), nor iterable unpacking (there's multi-target assignment though) nor descriptors in Ruby. Yes, Ruby and Python do overlap. But there are differences. – user7043 Dec 30 '11 at 14:39
  • Good, +1. To me, "assignment on steroids" is actually "poor man's pattern matching", but is incredibly useful nevertheless :) I'd also notice how flexible is parameter passing in functions: *args and **kwargs, painless way to map tuples and dicts to parameters, etc. – 9000 Apr 10 '12 at 19:21
  • I believe common lisp with CLOS hits all points except the use of layout-based syntax. Haskell isn't object-oriented (although there are OO extensions) but other than the metaclass point I believe it matches all of these features. – Jules Mar 6 '16 at 17:57

I guess the only thing that makes Python unique is the particular combination of features it exposes. This would be true for most programming languages.

Or there might be one small thing: I haven't seen the way Python explicitly passes self as a formal parameter to object member functions done in any other language. It's a small thing, and I don't see how this changes anything really.

But I'm not very fluent in Python, so there might be stuff I'm missing for sure!

| improve this answer | |
  • @delnan: Ah, I missed "explicitly pass self as a formal parameter".. Guess that's what I get for reading at 2am ;) – Demian Brecht Dec 30 '11 at 9:41
  • 4
    The explicit self occurs also in Oberon, fwiw – grrussel Dec 30 '11 at 19:41
  • An explicit self parameter is also used in the common lisp object system. CLOS provides multi-methods, however, which means that the self parameter isn't in any way special, like it is in python. – Jules Mar 6 '16 at 18:16

The automatic processing of docstrings to become properties of their owner. In general all of Python's brilliant introspection features make it a very unique language, from the ability to use help() to the ability to use __doc__ as a first-class property of an object. For example:

>>> class DocStringException(Exception):
...     """Error message is the same as docstring"""
...     def __str__(self):
...         return repr(self.__doc__)
>>> class ExampleException(DocStringException):
...     """An example happened"""
>>> raise ExampleException
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.ExampleException: 'An example happened'

Other useful introspection features:

  • help/help() - help with the interpreter / help with an object
  • keywords - python keywords
  • locals() - get the local names
  • globals() - get the global names
  • dir() - get an object's properties and methods
  • the .mro method., issubclass - understanding inheritance
  • id() - get the memory address of an object
| improve this answer | |
  • Ruby pretty much has the same power, as does Common Lisp, Clojure and many other, dynamic languages I believe. – Torbjørn Dec 31 '11 at 11:50
  • @Torbjørn which power? The automatic documentation, or the introspection features? – kojiro Dec 31 '11 at 14:22
  • I was thinking about both. Not exactly the say, but in spirit. I don't believe Ruby has the same documentation abilities, but introspection for sure. CL and Clojure has both features - and I believe the introspection there goes way beyond what you'll find in Python, since it's homoiconic. – Torbjørn Jan 1 '12 at 21:00
  1. Generator Expressions
  2. input() Let me explain, I have not seen a language (so far), where you can assign a value to a statement that prints something, it is like ruby's print/gets, but with a value assigned to the print, instead of: print "Foo" bar = gets
  3. yield
  4. Many types of datasets: ordereddict, namedtuple, array, list, tuple, dictionary
| improve this answer | |
  • Generator expressions can be implemented in Haskell using list comprehensions (Haskell lists are lazy, unlike python lists, so no specific syntax is needed for this). By "input" I assume you mean the python 3 function of that name (as the python 2 function is dangerous and shouldn't be used). It is true that this is an unusual combination of behaviour (although it is present in javascript - window.prompt - and BASIC, which is where I guess python borrowed it from) but it can be implemented trivially by the programmer ("input s = putStrLn s >> getStrLn" will do it for haskell). – Jules Mar 6 '16 at 18:43
  • A lazy language like Haskell doesn't really need yield - it can just return a list built up using the usual methods, and items will be generated on demand. Despite this, the library includes an explicit implementation of coroutines. The Haskell standard library contains all the mentioned data structures, and many more. – Jules Mar 6 '16 at 18:47

The thing is, Python is among very few languages with extremely low syntactic overhead giving it tremendous expressive powers: list/set/dict comprehensions, yield, decorators, eval, meta class programming, introspection, the optimized built-in data structures (lists, dicts, sets), all of those things conspire in a very nice way to give you (the developer) the power to express your thoughts in concise and elegant code almost as fast as you can think. I can't really think of any other languages with this killer set of features combined together.

| improve this answer | |
  • 1
    If you think Python has low syntactic overhead (despite having an obscenely complicated grammar and a relatively large amount of syntax sugar), what do you think of Scheme? – Tikhon Jelvis Apr 11 '12 at 6:29
  • Eval really shouldn't be used for any production program (although I grant it can be handy for quick hacks). As shown in comments for other questions, python is by no means unique in having these features. I believe, for instance, that clojure has all of the features you list, and most can be done with common lisp. – Jules Mar 6 '16 at 19:05

I would say it's use of indentation to enclose if statements and loops. Have not seen that in any other language.

I think its very handy because it makes it significantly more difficult to obfuscate python code!

It also seems to execute in a neat line by line manner with the exception of functions, and it can be interpreted as such too which is nice.

| improve this answer | |
  • 2
    Wikipedia knows a screen full of languages that do it as well. It's called the off-side rule. – user7043 Dec 30 '11 at 9:28
  • 3
    I do not understand It also seems to execute in a neat line by line manner with the exception of functions, and it can be interpreted as such too which is nice. What does it mean? – kojiro Dec 30 '11 at 14:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.