[Tutor] a question about MySQLdb in python

Peter Otten __peter__ at web.de
Tue Jan 10 15:40:57 CET 2012


贾晓磊 wrote:

> hi, all:
> 
>  python's version:  2.6.
>  MySQLdb version: 1.2.3.
> 
> I once encounter with a question like this:
> File
> "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.3-py2.6-linux-
x86_64.egg/MySQLdb/connections.py",
> 
> line 36, in defaulterrorhandler
>     raise errorclass, errorvalue
> OperationalError: (2006, 'MySQL server has gone away')
> 
> and i try to find the exception is how to perform to us in the source
> code.
> 
> when i read the source code, some questions puzzled me!
> 
> question 1: how to find the words "2006, 'MySQL server has gone away" in
> sourced code?

The 'MySQL server has gone away' message is probably in the client part of 
MySQL's C code. If you don't want to download that wholesale you can use a 
search engine like www.koders.com to look at some candidate files.

> question 2:  in MySQLdb/cursors.py , the method errorhandler() just
> receive two parameters such as exc,value when it's be invoked. however, in
> MySQLdb/connection.py, we define it as one receives 4 parameters such
> connection, cursor, erorclass, errorvalue
>                   a method should accepts 4 parameters is invoked by 2
> parameters. how to explain it?

Consider:

def defaulterrorhandler(four, three, two, one):
    ...
class Connection:
    errorhandler = defaulterrorhandler

connection = Connection()

At this point connection.errorhandler is a "bound method", i. e. argument 
"four" is the connection instance. The method expects only three more 
arguments. Now after

class Cursor:
    def __init__(self, connection):
        self.errorhandler = connection.errorhandler
    
cursor = Cursor(connection)

cursor.errorhandler can be called with three arguments and looking at the 
quoted code that indeed happens, e. g. in the following line:

>                 self.errorhandler(self, ProgrammingError, m.args[0])

You are probably conditioned to disregard the first argument, self, because 
of its name, but it counts just as well. The Cursor instance isn't added 
automatically as the binding mechanism only kicks in when a function is 
found in the class __dict__, but errorhandler is put into the __dict__ of 
the instance.

>>> class A:
...     pass
...
>>> def f(*args): print args
...
>>> a = A()
>>> a.f = f
>>> a.f()
()
>>> A.g = f
>>> a.g()
(<__main__.A instance at 0x7f8d50e765f0>,)


> question 3: in MySQLdb/connection.py,  the module cursors is been
> imported.
>  while,  In MySQLdb/cursors.py, some  methods such as errorhandler in
> MySQLdb/connection.py is been invoked.
>                 the two module, which one is execute first?  which one is
> added to mem first?

When a module is imported the code to create its functions, classes, and 
other values is executed. The code inside the functions and methods is not 
run until a function is explicitly invoked or a class is instantiated. For 
this reason (and because of the module cache) it is even possible (though 
strongly discouraged) to have two modules import each other:

$ cat one.py
print "importing one"

import two

def f(n):
    print "one.f(%s)" % n
    if n:
        two.f(n-1)
$ cat two.py
print "importing two"

import one

def f(n):
    print "two.f(%s)" % n
    if n:
        one.f(n-1)
$ python -c 'import one; one.f(5)'
importing one
importing two
one.f(5)
two.f(4)
one.f(3)
two.f(2)
one.f(1)
two.f(0)




More information about the Tutor mailing list