1

Where did Python borrow the concept of descriptor from?

Did Python borrow it from some other programming languages? In C#, I only see property, but not descriptor.

Will I benefit on not just descriptors but other concepts by learning that other language first, instead of learning Python directly?

Jens
  • 8,423
  • 9
  • 58
  • 78
Tim
  • 1
  • 141
  • 372
  • 590
  • C# has an ExpandoObject. However there is no 'true' descriptor equivalent which allows for general objects to dynamically intercept "any" member access. – user2864740 Jul 08 '17 at 00:54
  • https://stackoverflow.com/questions/2865865/are-there-equivalents-to-rubys-method-missing-in-other-languages - although a slightly different twist, "method missing" can be implemented with descriptors (although the converse is not strictly true). The linked question contains answers for a number of different languages/implementations which might provide insights. – user2864740 Jul 08 '17 at 00:55
  • So: 1. Places (very hard to find an authoritative answer, which makes this not a good question) 2. Yes (it would be hard to argue that Python development happened in a vacuum, again it is hard to find any objective answer) 3. Probably (and this is subjective and not a particularly good or interesting question) – user2864740 Jul 08 '17 at 01:02
  • Do Smalltalk, Java, and other pure or nonpure OO languages have descriptors? – Tim Jul 08 '17 at 01:03
  • The linked question provides a list to various equivalents for "method missing", of which descriptors (ref. getattr) are one form. It would be good to read. Java has no such equivalent. The other question is too broad with odd cross-cutting specificity. – user2864740 Jul 08 '17 at 01:04

1 Answers1

7

From Python itself. To quote Guido Van Rossum 1, descriptors were introduced in Python 2.2 as a generalization of the concept of bound methods, which was central to the implementation of classic classes in previous versions.

There are two common approaches for a language to support both functional and object oriented programming. Every callable is a method and functions are just methods of a hidden class, which is the approach adopted by Ruby; or every callable is a function and object methods are just functions with an implicit or explicit parameter that receives the object the method was called from, which is the approach adopted by Python.

In Python 2.1 and before, when an instance attribute lookup fails at the instance dictionary, the interpreter looks at the class and the base classes, recursively. If the attribute is found at a class dictionary and it's a function, the interpreter wraps it in a callable object that inserts the instance itself as the first parameter when it gets called. The wrapper binds the instance to the function, hence the name bound methods.

Descriptors are a generalization of that behavior. In Python 2.2 and later, the interpreter performs the attribute lookup in the same way, and when the attribute is found at a class dictionary and it has a __get__ method, this method gets called with the class and instance as arguments, and whatever is returned is used as the result of the attribute search. Instead of being a special object, the bound method wrapper is now just an ordinary object implementing a __get__ method, allowing us to customize it and implement special methods like classmethod and staticmethod. On top of that, we have the complementary methods __set__ and __delete__, generalizing the same behavior for assignment and deletion, allowing us to implement things like property and managed attributes of all kinds.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85
  • Thanks. (1) In Python "everything is a function"? Is a class a function, is a type a function, ...? (2) "There are two common approaches for a language to support both functional and object oriented programming." What is Scala's approach to support both functional and OO programming? What is Java's approach? C#'s? – Tim Jul 08 '17 at 02:42
  • I think Pedro is trying to make a statement about callables, and whether ultimately, methods are built on functions, or functions are built on methods, but it's a little mangled. Not everything in Python is a function, but the concept of methods is built on functions (functions implement the descriptor protocol, so if you define one on a class, when you access it from an instance it returns itself as a bound method). – ShadowRanger Jul 08 '17 at 02:45
  • @Tim Poor choice of words. I edited the question to clarify that I'm talking about callables, not every entity in the language. As for the other questions in your comment, it would be better if you created a new question for that, asking how exactly Scala, Java, C#, etc, implement it. – Pedro Werneck Jul 08 '17 at 02:48
  • Ok, I will. Where or how did you learn that there are two approaches for a language to support both functional and object oriented programming? – Tim Jul 08 '17 at 02:58
  • 1
    @Tim: Nothing requires only those two approaches, but it happens to be convenient to build one concept in terms of the other, so you tend to see one of those options for higher level languages. In theory, you could have a language that implemented them both in terms of class constructors where assignment of the result triggered a conversion to the result; it would be weird, but it's possible. The two approaches mentioned are just the saner approaches available when you'd prefer to avoid inventing the wheel twice for near identical purposes. – ShadowRanger Jul 08 '17 at 03:12
  • @Tim I said they are two common approaches, not that they are the only ones. – Pedro Werneck Jul 08 '17 at 03:18
  • This doesn't really answer the question. The question asks about the history in the broader context of programming languages; this talks about the history in Python. I actually suspect there's an interesting answer going back to the meta-object protocols of Smalltalk and CLOS, but I don't know either well enough to compare and contrast – Sam Hartman Jul 08 '17 at 03:20
  • @SamHartman He's asking where did Python borrow the concept from, not if other languages have a similar concept. Python's bound method concept is just an implicit generalization of how you would write OO in a pure functional language. In that sense you can say it's similar to CLOS defmethod, but I don't think it was "borrowed" from it. – Pedro Werneck Jul 08 '17 at 03:31