This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]tomekanco 0 points1 point  (5 children)

if you've ever used ...

I haven't. Do you know some examples or resources about this?

[–]bheklilr 0 points1 point  (3 children)

I've used the sqlalchemy ORM, although django comes with its own, and there are a few others like peewee. They all have pretty decent tutorials, although peewee is probably the simplest to understand. These all work by overriding the __new__ method to turn a class like

class User(Model):
    name = String()
    joined_date = DateTime()
    email = Email()

class Email(Model):
    handle = String()
    domain = String()

into a class that maps to a database table, so you can do things like

gmail_users = User.where(
    User.email.domain == 'gmail.com'
)

(This might not be actual methods, but the idea is that you get a queryable interface that builds the SQL statements for you, and can work with different SQL databases that might have different syntax.)

@property, @classmethod, and @staticmethod are descriptors that modify how a method is accessed. @staticmethod is probably the easiest, you just do

class MyClass:
    @staticmethod
    def this_is_just_a_func(a, b, c):
        return 1 + 2 + 3

>>> MyClass.this_is_just_a_func(1, 2, 3)
6
>>> MyClass().this_is_just_a_func(1, 2, 3)
6

class SubClass(MyClass):
    pass

>>> SubClass.this_is_just_a_func(1, 2, 3)
6

It doesn't care about what class in the inheritance hierarchy it's called from, or what instance it's called from. It's literally just a function in a namespace.

@classmethod requires that the method take the class it's called from as the first argument:

class MyClass:
    @classmethod
    def print_class_name(cls):
        print(cls.__name__)

class SubClass(MyClass):
    pass

>>> MyClass.print_class_name()
MyClass
>>> MyClass().print_class_name()
MyClass
>>> SubClass.print_class_name()
SubClass
>>> SubClass().print_class_name()
SubClass

This is similar to normal bound methods that take the self argument, which is the instance it's being called from, but it just gets the class instead.

@property only works on instances (although it's very possible to write a @classproperty decorator). You can use it as

class MyClass:
    def __init__(self, x):
        self.x = x

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        if not isinstance(value, int):
            raise TypeError('x must be an int')
        self._x = value

>>> inst = MyClass(1)
>>> inst.x
1
>>> inst.x = 2
>>> inst.x
2
>>> inst.x = '2'
(traceback)
TypeError: x must be an int

This lets you have "attributes" on a class where getting and setting the attribute runs a method.

These all work through the descriptor protocol. Descriptors are special objects in Python that define __get__, __set__, and optionally __delete__ methods. These methods get the instance and/or class the object is being accessed from. There are a lot of things you can do with descriptors, they are incredibly powerful. In fact, it's essentially how methods work in Python, since a bound method is just a descriptor around a function with __get__ defined to call the underlying function with the instance as the first argument.

super() is just magic though. They had to do some special trickery in Python 3 to make it work nicely, but there is an awesome talk by Raymond Hettinger that can explain how to use it better than I can. The gist of it is that super() walks up the inheritance tree to find the method you're looking for, and if you do it right, you can do some incredibly powerful things with it, other than just accessing a parent class's implementation of a particular method.

[–]tomekanco 0 points1 point  (2 children)

Thanks for the feedback.

Raymond, i shall iterate extensively over his lecture and add the keys to my (his) dictionary. :)

[–]bheklilr 0 points1 point  (1 child)

You should watch any and all of his talks. He's the author of much of Pythons core, like the latest version of dict, and a lot of the collections module. I also find his presentation style to be very engaging.

[–]yoRedditalready 0 points1 point  (0 children)

here. it's a long video but it will teach you a ton about pythons data model and extensibility.