Re: difference between class methods and instance methods
Duncan Booth wrote: Diez B. Roggisch wrote: Duncan Booth wrote: Bound methods get created whenever you reference a method of an instance. That did escape me so far - interesting. Why is it that way? I'd expect that creating a bound method from the class and then storing it in the objects dictionary is what happens. If you had a class with 50,000 methods it could take quite a while to create instances, consider Zope as an example where every object acquires large numbers of methods most of which are completely irrelevant. Even outside Zope most objects never have all their methods called: dict, for example, has 38 methods but most of them get little or no use. So why couldn't bound methods be created like lazy properties: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363602 So that they're not created at instance creation time, but they're only created once, when first accessed? Not that I've ever had any problems with the speed or memory usage of bound methods -- I'm just curious about the design decision. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Op 2005-02-18, Diez B. Roggisch schreef <[EMAIL PROTECTED]>: >> This is badly wrong. John was correct. >> >> Bound methods get created whenever you reference a method of an instance. >> If you are calling the method then the bound method is destroyed as soon >> as the call returns. You can have as many different bound methods created >> from the same unbound method and the same instance as you want: > > That did escape me so far - interesting. Why is it that way? I'd expect that > creating a bound method from the class and then storing it in the objects > dictionary is what happens. > No. What happens is that functions are descriptors. So if you assign a function to a class attribute any access to this attribute will call the __get__ method which will create a bound method if the access was through an instance or an unbound method if the access was through the class. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Diez B. Roggisch wrote: >> This is badly wrong. John was correct. >> >> Bound methods get created whenever you reference a method of an >> instance. If you are calling the method then the bound method is >> destroyed as soon as the call returns. You can have as many different >> bound methods created from the same unbound method and the same >> instance as you want: > > That did escape me so far - interesting. Why is it that way? I'd > expect that creating a bound method from the class and then storing it > in the objects dictionary is what happens. > If you had a class with 50,000 methods it could take quite a while to create instances, consider Zope as an example where every object acquires large numbers of methods most of which are completely irrelevant. Even outside Zope most objects never have all their methods called: dict, for example, has 38 methods but most of them get little or no use. Creating a bound method is a comparatively cheap operation, its a small object which just has to hold references to the instance and the function. The memory allocation is fast, because Python keeps lists of appropriately sized buckets for small objects. -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
> This is badly wrong. John was correct. > > Bound methods get created whenever you reference a method of an instance. > If you are calling the method then the bound method is destroyed as soon > as the call returns. You can have as many different bound methods created > from the same unbound method and the same instance as you want: That did escape me so far - interesting. Why is it that way? I'd expect that creating a bound method from the class and then storing it in the objects dictionary is what happens. -- Regards, Diez B. Roggisch -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John wrote: >>inst = C() >>f1 = inst.foo >>f2 = inst.foo >>f1, f2 >> >> (>, > method C.foo of <__main__.C instance at 0x00B03F58>>) >> > > I just wanted to interject, although those two hex > numbers in the above line are the same, calling > id() on f1 and f2 produces two *different* numbers, > which agrees with the point you made. Yes, note that the numbers are in the repr of C() and are actually id(inst). A common mistake seems to be for people to do: >>> inst = C() >>> id(inst.foo), id(inst.foo) (11803664, 11803664) and conclude that the bound methods are the same. They aren't, but if you just take the id of an object and throw it away then the next object of similar size can [and with the current implementation probably will] be allocated at the same location. -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Op 2005-02-17, Diez B. Roggisch schreef <[EMAIL PROTECTED]>: > John wrote: >> ... hmm... bound methods get created each time you make >> a call to an instance method via an instance of the given class? > > No, they get created when you create an actual instance of an object. I'm not so sure about that. Take the following code: >>> class A: ... def m(): ... pass ... >>> a = A() >>> u = a.m >>> u is a.m False If bound methods were created at instance creation one would expect a True result here instead of False. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
"John M. Gabriele" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > And if anyone's *really* daring: > Where do the so-called "static methods" fit into all this? > By the name of them, it sounds like the same thing as class > methods... No, not at all. So called 'static methods' are class function attibutes that are marked to *not* be given neither the method wrapping treatment nor the first-arg binding treatment when accessed, but to be left as they are. To me, this means that they are not methods but just functions. >>> class C: ... def f(): pass ... def g(): pass ... g = staticmethod(g) ... >>> C.f >>> C.g Terry J. Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Duncan Booth wrote: [snip] Bound methods get created whenever you reference a method of an instance. If you are calling the method then the bound method is destroyed as soon as the call returns. You can have as many different bound methods created from the same unbound method and the same instance as you want: inst = C() f1 = inst.foo f2 = inst.foo f1, f2 (>, >) I just wanted to interject, although those two hex numbers in the above line are the same, calling id() on f1 and f2 produces two *different* numbers, which agrees with the point you made. f1 is f2 False f1 is inst.foo False Every reference to inst.foo is a new bound method. -- --- remove zees if replying via email --- -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Diez B. Roggisch wrote: > John wrote: >> ... hmm... bound methods get created each time you make >> a call to an instance method via an instance of the given class? > > No, they get created when you create an actual instance of an object. > So only at construction time. Creating them means taking the unbound > method and binding the created object as first argument to the method. > Thus each instance of a class Foo with a method bar has its own > instance of bar - the bound method bar. But only one per object. > > This is badly wrong. John was correct. Bound methods get created whenever you reference a method of an instance. If you are calling the method then the bound method is destroyed as soon as the call returns. You can have as many different bound methods created from the same unbound method and the same instance as you want: >>> inst = C() >>> f1 = inst.foo >>> f2 = inst.foo >>> f1, f2 (>, >) >>> f1 is f2 False >>> f1 is inst.foo False >>> Every reference to inst.foo is a new bound method. -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John wrote: >> Note that it doesn't matter whether you call instance.foo(2) >> directly, or bind instance.foo to a variable first. Either will >> create a *new* bound method object, and the correct instance is used >> for the call. > > Za! What do you mean, "create a new bound method object"? I *already* > created that method when I def'd it inside the 'class Demo' statement, > no? > The def statement creates a function. Accessing the method through the class creates a brand new unbound method from the function. Every access of the method through the class creates a separate unbound method. Accessing the method through the instance creates a brand new bound method. Every such access creates a separate bound method. > > ... hmm... bound methods get created each time you make > a call to an instance method via an instance of the given class? > you've got it. -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John wrote: Steven Bethard wrote: John M. Gabriele wrote: class C(object): @classmethod def f(cls, *args): # do stuff Sorry -- I'm not as far along as you suspect. :) I've never yet seen this "@classmethod" syntax. I'm supposing that it's part of this so-called "new-style" class syntax. This is syntactic sugar in Python 2.4 for: class C(object): def f(cls, *args): # do stuff f = classmethod(f) So if you'd like to check the docs, look in the builtins for classmethod (and staticmethod): http://docs.python.org/lib/built-in-funcs.html From your reply, I gather that, unless I'm using this special syntax (@classmethod or @staticmethod), all my def's are supposed to take 'self' as their first arg. Yup. You're of course welcome to name it whatever you like, but the methods defined in your class (when not wrapped with classmethod, staticmethod, etc.) will all be called with an instance of the class as their first argument. So you need to make sure 'self' or something like it is the first parameter to the function. So then, are all def's -- that take 'self' as their first -- argument -- in a class statement, instance methods? Basically, yes. (Again, assuming they're not wrapped with anything.) Consider the difference between str.join and ''.join: py> str.join > py> ', '.join > Hmm... weird. Ok, the point here is that str.join and ', '.join are not the same object. The reason is that, when the ', ' instance of str is created, new "bound method" objects are created for each of the instance methods in str. These "bound methods" all know that the first argument to their functions is ', '. py> ', '.join(['a', 'b', 'c']) 'a, b, c' Check. py> str.join(', ', ['a', 'b', 'c']) 'a, b, c' [snip] What's happening here? str.join is the "unbound method" of the str object. So just like you have to declare 'self' as the first argument of all your instance methods, the writer of the str object methods also declared 'self' as the first argumetn to str.join. So str.join looks something like: class str(object): ... def join(self, sequence): ... So when you access it like str.join(...) you should be passing it an instance and a sequence. On the other hand, the "bound method" created for ', ' has already bound the instance, so it no longer expects the 'self' argument to be passed in. HTH, STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
> O. Unlike C++, where methods are not first class objects > and you only have *one* that gets shared by all instances. Exactly - so unlike in c++, where you have to do ugly hacks if e.g. a C-lib takes a callback and you want to pass an instance method, you can do that in python. It's really great. -- Regards, Diez B. Roggisch -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Diez B. Roggisch wrote: John wrote: ... hmm... bound methods get created each time you make a call to an instance method via an instance of the given class? No, they get created when you create an actual instance of an object. So only at construction time. Creating them means taking the unbound method and binding the created object as first argument to the method. Thus each instance of a class Foo with a method bar has its own instance of bar - the bound method bar. But only one per object. O. Unlike C++, where methods are not first class objects and you only have *one* that gets shared by all instances. I'm getting it. Thanks for the reply. :) ---J -- --- remove zees if replying via email --- -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John wrote: > ... hmm... bound methods get created each time you make > a call to an instance method via an instance of the given class? No, they get created when you create an actual instance of an object. So only at construction time. Creating them means taking the unbound method and binding the created object as first argument to the method. Thus each instance of a class Foo with a method bar has its own instance of bar - the bound method bar. But only one per object. -- Regards, Diez B. Roggisch -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Duncan Booth wrote: John M. Gabriele wrote: I've done some C++ and Java in the past, and have recently learned a fair amount of Python. One thing I still really don't get though is the difference between class methods and instance methods. I guess I'll try to narrow it down to a few specific questions, but any further input offered on the subject is greatly appreciated: I'll try not to cover the same ground as Steven did in his reply. Thanks for taking the time to reply Duncan. 1. Are all of my class's methods supposed to take 'self' as their first arg? consider this: class Demo(object): def foo(self, x): print self, x @classmethod def clsmethod(cls, x): print cls, x @staticmethod def stmethod(x): print x instance = Demo() Calling a bound method, you don't pass an explicit self parameter, but the method receives a self parameter: bound = instance.foo bound(2) <__main__.Demo object at 0x00B436B0> 2 > Note that it doesn't matter whether you call instance.foo(2) directly, or bind instance.foo to a variable first. Either will create a *new* bound method object, and the correct instance is used for the call. Za! What do you mean, "create a new bound method object"? I *already* created that method when I def'd it inside the 'class Demo' statement, no? This is significantly different from languages such as C++ and Javascript which are a real pain if you want to use a method as a callback. Calling an unbound method, you pass a self parameter explicitly (and it must be an instance of the class, *or an instance of a subclass*: unbound = Demo.foo unbound(instance, 2) <__main__.Demo object at 0x00B436B0> 2 A! See, coming from C++, the first thing I thought when I saw what you just wrote was, "whoops, he shouldn't be calling that instance method via the class name -- it's a bad habit". Now I think I see what you mean: you may call an instance method in two ways: via an instance where you don't pass in anything for 'self', and via the class name, where you must supply a 'self'. Again is doesn't matter whether you do this in one step or two. The usual case for using an unbound method is when you have overridden a method in a derived class and want to pass the call on to a base class. e.g. Ok. Interesting. class Derived(Demo): def foo(self, x): Demo.foo(self, x) A class method is usually called through the class rather than an instance, and it gets as its first parameter the actual class involved in the call: Demo.clsmethod(2) 2 Derived.clsmethod(2) 2 Check. You can call a class method using an instance of the class, or of a subclass, but you still the get class passed as the first parameter rather than the instance: d = Derived d.clsmethod(2) 2 Ok, so it looks like it may lead to confusion if you do that. I wonder why the language allows it... A common use for class methods is to write factory functions. This is because you can ensure that the object created has the same class as the parameter passed in the first argument. Alternatively you can use class methods to control state related to a specific class (e.g. to count the number of instances of that exact class which have been created.) There is no equivalent to a class method in C++. Right. I see -- because in Python, a reference the actual class object is implicitly passed along with the method call. Whereas, C++ doesn't even have "class objects" to begin with. Static methods are like static methods in C++. You can call them through the class or a subclass, or through an instance, but the object used in the call is not passed through to the method: Demo.stmethod(2) 2 instance.stmethod(2) 2 Derived.stmethod(2) 2 d.stmethod(2) 2 2. Am I then supposed to call them with MyClass.foo() or instead: bar = MyClass() bar.foo() ? If you have an instance then use it. If the class method is a factory then you might want to create a new object of the same type as some existing object (but not a simple copy since you won't get any of the original object's state). Mostly though you know the type of the object you want to create rather than having an existing instance lying around. 3. Is "bound method" a synonym for instance method? Close but not quite. It is a (usually transient) object created from an unbound instance method for the purposes of calling the method. ... hmm... bound methods get created each time you make a call to an instance method via an instance of the given class? 4. Is "unbound method" a synonym for class method? Definitely not. Right. :) And if anyone's *really* daring: Where do the so-called "static methods" fit into all this? By the name of them, it sounds like the same thing as class methods... See above. -- --- remove zees if replying via email --- -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
Steven Bethard wrote: John M. Gabriele wrote: 1. Are all of my class's methods supposed to take 'self' as their first arg? If by "class's methods" you mean methods on which you called classmethod, then no, they shouldn't take a 'self' parameter, they should take a 'cls' parameter because the first argument to the function will be the class: class C(object): @classmethod def f(cls, *args): # do stuff Sorry -- I'm not as far along as you suspect. :) I've never yet seen this "@classmethod" syntax. I'm supposing that it's part of this so-called "new-style" class syntax. When I ask "are all my class's methods...", I mean, when I'm writing a class statement and the def's therein -- are all those def's supposed to take 'self' as their first arg. From your reply, I gather that, unless I'm using this special syntax (@classmethod or @staticmethod), all my def's are supposed to take 'self' as their first arg. Undecorated methods (e.g. those that are not wrapped with classmethod or staticmethod) should, on the other hand, take a 'self' parameter. Ok. Check. So then, are all def's -- that take 'self' as their first -- argument -- in a class statement, instance methods? 2. Am I then supposed to call them with MyClass.foo() or instead: bar = MyClass() bar.foo() Classmethods should be called from the class. Python allows you to call them from the instance, but this almost never does what you want, e.g.: py> d = {} py> d.fromkeys(range(4)) {0: None, 1: None, 2: None, 3: None} py> d {} Note that 'd' is not updated -- I called a classmethod, not an instancemethod. If I had called dict.fromkeys instead, this would have been clearer. Right. An important lesson in C++ as well. 3. Is "bound method" a synonym for instance method? 4. Is "unbound method" a synonym for class method? No. To simplify things a little[1], a "bound method" is an instance method that has been associated with a specific instance, and an "unbound method" is an instance method that has not been associated with a specific instance. Ok! Now I'm making some headway. *This* is getting at the crux of the biscuit. Consider the difference between str.join and ''.join: py> str.join > py> ', '.join > Hmm... weird. py> str.join(['a', 'b', 'c']) Traceback (most recent call last): File "", line 1, in ? TypeError: descriptor 'join' requires a 'str' object but received a 'list' > Right -- 'cause there's no actual instance of a string to do the joining. Check. py> ', '.join(['a', 'b', 'c']) 'a, b, c' Check. py> str.join(', ', ['a', 'b', 'c']) 'a, b, c' Ack! Now you're creeping me out. Looking at the doc for str.join: | py> help( str.join ) | Help on method_descriptor: | | join(...) | S.join(sequence) -> string | | Return a string which is the concatenation of the strings in the | sequence. The separator between elements is S. | It says that you didn't call that method correctly. Yet it works anyway!? What's happening here? In the example above, you can see that str.join is an "unbound method" -- when I try to call it without giving it an instance, it complains. On the other hand, ', '.join is a "bound method" because it has been bound to a specific instance of str (in this case, the instance ', '). When I call it without an instance, it doesn't complain because it's already been bound to an instance. Ok. I see that distinction. Thanks. Where do the so-called "static methods" fit into all this? By the name of them, it sounds like the same thing as class methods... Staticmethods, like classmethods, are associated with the class object, not the instance objects. That makes sense. The main difference is that when a staticmethod is called, no additional arguments are supplied, while when a classmethod is called, a first argument, the class, is inserted in the argument list: py> class C(object): ... @classmethod ... def f(*args): ... print args ... @staticmethod ... def g(*args): ... print args ... py> C.f(1, 2, 3) (, 1, 2, 3) py> C.g(1, 2, 3) (1, 2, 3) STeVe Thanks for that nice example. It looks like you're always supposed to call both class and static methods via the class name (rather than an instance name). I'll read up on what this new @classmethod and @staticmethod syntax means. [1] Technically, I think classmethods could also considered to be "bound methods" because in this case, the method is associated with a specific instance of 'type' (the class in which it resides) -- you can see this in the first argument that is supplied to the argument list of a classmethod. -- --- remove zees if replying via email --- -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John M. Gabriele wrote: > I've done some C++ and Java in the past, and have recently learned > a fair amount of Python. One thing I still really don't get though > is the difference between class methods and instance methods. I > guess I'll try to narrow it down to a few specific questions, but > any further input offered on the subject is greatly appreciated: I'll try not to cover the same ground as Steven did in his reply. > > 1. Are all of my class's methods supposed to take 'self' as their > first arg? consider this: >>> class Demo(object): def foo(self, x): print self, x @classmethod def clsmethod(cls, x): print cls, x @staticmethod def stmethod(x): print x >>> instance = Demo() Calling a bound method, you don't pass an explicit self parameter, but the method receives a self parameter: >>> bound = instance.foo >>> bound(2) <__main__.Demo object at 0x00B436B0> 2 Note that it doesn't matter whether you call instance.foo(2) directly, or bind instance.foo to a variable first. Either will create a *new* bound method object, and the correct instance is used for the call. This is significantly different from languages such as C++ and Javascript which are a real pain if you want to use a method as a callback. Calling an unbound method, you pass a self parameter explicitly (and it must be an instance of the class, *or an instance of a subclass*: >>> unbound = Demo.foo >>> unbound(instance, 2) <__main__.Demo object at 0x00B436B0> 2 Again is doesn't matter whether you do this in one step or two. The usual case for using an unbound method is when you have overridden a method in a derived class and want to pass the call on to a base class. e.g. >>> class Derived(Demo): def foo(self, x): Demo.foo(self, x) A class method is usually called through the class rather than an instance, and it gets as its first parameter the actual class involved in the call: >>> Demo.clsmethod(2) 2 >>> Derived.clsmethod(2) 2 You can call a class method using an instance of the class, or of a subclass, but you still the get class passed as the first parameter rather than the instance: >>> d = Derived >>> d.clsmethod(2) 2 A common use for class methods is to write factory functions. This is because you can ensure that the object created has the same class as the parameter passed in the first argument. Alternatively you can use class methods to control state related to a specific class (e.g. to count the number of instances of that exact class which have been created.) There is no equivalent to a class method in C++. Static methods are like static methods in C++. You can call them through the class or a subclass, or through an instance, but the object used in the call is not passed through to the method: >>> Demo.stmethod(2) 2 >>> instance.stmethod(2) 2 >>> Derived.stmethod(2) 2 >>> d.stmethod(2) 2 >>> > > 2. Am I then supposed to call them with MyClass.foo() or instead: > > bar = MyClass() > bar.foo() > ? If you have an instance then use it. If the class method is a factory then you might want to create a new object of the same type as some existing object (but not a simple copy since you won't get any of the original object's state). Mostly though you know the type of the object you want to create rather than having an existing instance lying around. > > 3. Is "bound method" a synonym for instance method? Close but not quite. It is a (usually transient) object created from an unbound instance method for the purposes of calling the method. > > 4. Is "unbound method" a synonym for class method? Definitely not. > > And if anyone's *really* daring: > Where do the so-called "static methods" fit into all this? > By the name of them, it sounds like the same thing as class > methods... See above. -- http://mail.python.org/mailman/listinfo/python-list
Re: difference between class methods and instance methods
John M. Gabriele wrote: 1. Are all of my class's methods supposed to take 'self' as their first arg? If by "class's methods" you mean methods on which you called classmethod, then no, they shouldn't take a 'self' parameter, they should take a 'cls' parameter because the first argument to the function will be the class: class C(object): @classmethod def f(cls, *args): # do stuff Undecorated methods (e.g. those that are not wrapped with classmethod or staticmethod) should, on the other hand, take a 'self' parameter. 2. Am I then supposed to call them with MyClass.foo() or instead: bar = MyClass() bar.foo() Classmethods should be called from the class. Python allows you to call them from the instance, but this almost never does what you want, e.g.: py> d = {} py> d.fromkeys(range(4)) {0: None, 1: None, 2: None, 3: None} py> d {} Note that 'd' is not updated -- I called a classmethod, not an instancemethod. If I had called dict.fromkeys instead, this would have been clearer. 3. Is "bound method" a synonym for instance method? 4. Is "unbound method" a synonym for class method? No. To simplify things a little[1], a "bound method" is an instance method that has been associated with a specific instance, and an "unbound method" is an instance method that has not been associated with a specific instance. Consider the difference between str.join and ''.join: py> str.join py> ', '.join py> str.join(['a', 'b', 'c']) Traceback (most recent call last): File "", line 1, in ? TypeError: descriptor 'join' requires a 'str' object but received a 'list' py> ', '.join(['a', 'b', 'c']) 'a, b, c' py> str.join(', ', ['a', 'b', 'c']) 'a, b, c' In the example above, you can see that str.join is an "unbound method" -- when I try to call it without giving it an instance, it complains. On the other hand, ', '.join is a "bound method" because it has been bound to a specific instance of str (in this case, the instance ', '). When I call it without an instance, it doesn't complain because it's already been bound to an instance. Where do the so-called "static methods" fit into all this? By the name of them, it sounds like the same thing as class methods... Staticmethods, like classmethods, are associated with the class object, not the instance objects. The main difference is that when a staticmethod is called, no additional arguments are supplied, while when a classmethod is called, a first argument, the class, is inserted in the argument list: py> class C(object): ... @classmethod ... def f(*args): ... print args ... @staticmethod ... def g(*args): ... print args ... py> C.f(1, 2, 3) (, 1, 2, 3) py> C.g(1, 2, 3) (1, 2, 3) STeVe [1] Technically, I think classmethods could also considered to be "bound methods" because in this case, the method is associated with a specific instance of 'type' (the class in which it resides) -- you can see this in the first argument that is supplied to the argument list of a classmethod. -- http://mail.python.org/mailman/listinfo/python-list
difference between class methods and instance methods
I've done some C++ and Java in the past, and have recently learned a fair amount of Python. One thing I still really don't get though is the difference between class methods and instance methods. I guess I'll try to narrow it down to a few specific questions, but any further input offered on the subject is greatly appreciated: 1. Are all of my class's methods supposed to take 'self' as their first arg? 2. Am I then supposed to call them with MyClass.foo() or instead: bar = MyClass() bar.foo() ? 3. Is "bound method" a synonym for instance method? 4. Is "unbound method" a synonym for class method? And if anyone's *really* daring: Where do the so-called "static methods" fit into all this? By the name of them, it sounds like the same thing as class methods... Much thanks, ---J -- --- if replying via email, remove zees --- -- http://mail.python.org/mailman/listinfo/python-list