Ryan Johnson <rj.amdphr...@gmail.com> writes: > I am working on using mysql.connector in a class and have found an example of > how to create a single connection that spans the lifetime of all instances of > the class: > > https://softwareengineering.stackexchange.com/a/358061/317228 > > however, I do not understand a few things about the class, including > > 1. Why it is subclassed as an object: `class Postgres(object):` ? I thought > classes were necessarily objects.
This obviously is for Python 2. For historical reasons, Python 2 has two kinds of "class"es, old style and new style classes. As new style classes were introduced into Python 2, a need arose to distinguish them from old style classes: a new style class can be recognized by the fact that is has "object" in its inheritance graph. I.e. "class Postgres(object)" indicates that "Postgres" is a new style class. Python 3 only supports new style classes. Every class implicitely inherits "object". > 2. Why is this portion of code directly addressing the class, instead of > using the `cls` reference variable? > connection = Postgres._instance.connection = psycopg2.connect(**db_config) > cursor = Postgres._instance.cursor = connection.cursor() There is not real reason to use "Postgres" in this place instead of "cls". > 3. And is it me or does anyone else think {anydb}.connector’s usage is messy > and inelegant? Ex: > print('connecting to PostgreSQL database...') > connection = Postgres._instance.connection = psycopg2.connect(**db_config) > cursor = Postgres._instance.cursor = connection.cursor() > cursor.execute('SELECT VERSION()') > db_version = cursor.fetchone() > Why can’t we associate the focus of the connection with the connection > itself, instead of creating a separate cursor object? I think this is meant as an example to demonstrate how to implement singleton database connections. As such, it has print statements to demonstrates what is going on (i.e. to convince you that several functions instantiating "postgres" indeed share a common postgres connection. In your own productive class, you would likely not have "print" statements. > Also, within the code example, and in Python in general, why does there needs > to be a __new__ constructor when there’s an __init__ constructor? "__new__" essentially allocated the storage for a class instance, "__init__" initializes this storage. You rarely need "__new__". Typically, you need it only for classes where the amount of storage initially allocated for a class instance depends on the instance's value. An example is a class inheriting from "tuple": A "tuple" directly stores references to its components in itself - therefore, the amount of storage depends on the number of components. Most classes store the "content" of an instance in an extensible structure of the instance (the so called "instance dict"). They can use a standard "__new__" implementation and do not require there own. The example you reference could be rewritten to avoid the use of "__new__" (and integrate its functionality instead into "__init__"). Note that "__new__" is a class method, "__init__" is (by default) an instance method. This means, the the "cls" in "__new__" corresponds to "self.__class__" in "__init__". >I’ve read about the usage of singletons. It seems you could create singletons >within __init__ or __new__ . You are right. -- https://mail.python.org/mailman/listinfo/python-list