I was checking the code of the toolz library's groupby
function in Python and I found this:
def groupby(key, seq):
""" Group a collection by a key function
"""
if not callable(key):
key = getter(key)
d = collections.defaultdict(lambda: [].append)
for item in seq:
d[key(item)](item)
rv = {}
for k, v in d.items():
rv[k] = v.__self__
return rv
Is there any reason to use rv[k] = v.__self__
instead of rv[k] = v
?
self. __class__ is a reference to the type of the current instance. Throwing an exception here is like using an assert statement elsewhere in your code, it protects you from making silly mistakes. type() should be preferred over self.
The self keyword is used to represent an instance (object) of the given class. In this case, the two Cat objects cat1 and cat2 have their own name and age attributes. If there was no self argument, the same class couldn't hold the information for both these objects.
Need for Self in PythonPython uses the self parameter to refer to instance attributes and methods of the class. Unlike other programming languages, Python does not use the “@” syntax to access the instance attributes. This is the sole reason why you need to use the self variable in Python.
Through the self parameter, instance methods can freely access attributes and other methods on the same object. This gives them a lot of power when it comes to modifying an object's state. Not only can they modify object state, instance methods can also access the class itself through the self.
self represents the instance of the class. By using the “self” keyword we can access the attributes and methods of the class in python. It binds the attributes with the given arguments.
self as it suggests, refers to itself - the object which has called the method. That is, if you have N objects calling the method, then self.a will refer to a separate instance of the variable for each of the N objects. Imagine N copies of the variable a for each object
It is important to use the self parameter inside an object's method if you want to persist the value with the object. If, for instance, you implement the __init__ method like this: Your x and y parameters would be stored in variables on the stack and would be discarded when the init method goes out of scope.
self is parameter in function and user can use another parameter name in place of it.But it is advisable to use self because it increase the readability of code. Writing code in comment? Please use ide.geeksforgeeks.org , generate link and share the link here.
This is a somewhat confusing trick to save a small amount of time:
We are creating a defaultdict
with a factory function that returns a bound append
method of a new list instance with [].append
. Then we can just do d[key(item)](item)
instead of d[key(item)].append(item)
like we would have if we create a defaultdict
that contains lists. If we don't lookup append
everytime, we gain a small amount of time.
But now the dict
contains bound methods instead of the lists, so we have to get the original list instance back via __self__
.
__self__
is an attribute described for instance methods that returns the original instance. You can verify that with this for example:
>>> a = []
>>> a.append.__self__ is a
True
This is a somewhat convoluted, but possibly more efficient approach to creating and using a defaultdict
of lists.
First, remember that the default item is lambda: [].append
. This means create a new list, and store a bound append
method in the dictionary. This saves you a method bind on every further append to the same key, and the garbage collect that follows. For example, the following more standard approach is less efficient:
d = collections.defaultdict(list)
for item in seq:
d[key(item)].append(item)
The problem then becomes how to get the original lists back out of the dictionary, since the reference is not stored explicitly. Luckily, bound methods have a __self__
attribute which does just that. Here, [].append.__self__
is a reference to the original []
.
As a side note, the last loop could be a comprehension:
return {k: v.__self__ for k, v in d.items()}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With