[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