我正在学习如何编程和处理Python类,并发现了这个问题。你知道吗
我有这些文件(示例.py)在这个文件中,我导入了两个类。你知道吗
示例.py
..
from class_folder.automobile import Class_Automobile
from class_folder.catalog import Class_Catalog
class_automobile = Class_Automobile()
class_catalog = Class_Catalog()
..
内部汽车.py有以下代码:
from pdo_mysql import Pdo_Mysql
class Class_Automobile(object):
"""
Description
"""
__pdo_mysql_intern = None
def __init__(self):
self.__pdo_mysql_intern = Pdo_Mysql('host', 'user', 'password', 'db')
## End def init
def Validate_Make(self, make_search):
query_make = 'make_text = %s '
result = self.__pdo_mysql_intern.select('make', query_make, 'id_make', make=make_search)
return result
## End function Validate Make
在目录.py文件包含以下信息:
from pdo_mysql import Pdo_Mysql
class Class_Catalog(object):
"""
Description
"""
__pdo_mysql_intern = None
def __init__(self):
self.__pdo_mysql_intern = Pdo_Mysql('host', 'user', 'password', 'db2')
## End def init
最后是pdo_mysql.py版本文件包含以下内容:
import MySQLdb, sys
class Pdo_Mysql(object):
"""
Description
"""
__instance = None
__host = None
__user = None
__password = None
__database = None
__session = None
__connection = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super(Pdo_Mysql, cls).__new__(cls,*args,**kwargs)
return cls.__instance
## End __new__
def __init__(self, host='localhost', user='root', password='', database=''):
self.__host = host
self.__user = user
self.__password = password
self.__database = database
## __init__
def _open(self):
try:
cnx = MySQLdb.connect(self.__host, self.__user, self.__password, self.__database)
self.__connection = cnx
self.__session = cnx.cursor()
except MySQLdb.Error as e:
print "Error %d: %s" % (e.args[0],e.args[1])
## End function open
def _close(self):
self.__session.close()
self.__connection.close()
## End function close
def select(self, table, where=None, *args, **kwargs):
result = None
query = 'SELECT '
keys = args
values = tuple(kwargs.values())
l = len(keys) - 1
for i, key in enumerate(keys):
query += "`"+key+"`"
if i < l:
query += ","
## End for keys
query += 'FROM %s' % table
if where:
query += " WHERE %s" % where
## End if where
self._open()
self.__session.execute(query, values)
result = [item[0] for item in self.__session.fetchall()]
self._close()
return result
## End function select
当我运行示例.py我有这个问题,不知怎的当我称之为
validate_information = class_automobile.Validate_Make(make)
我得到了这个答复
File "/Library/Python/2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "/Library/Python/2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1146, "Table 'db2.make' doesn't exist")
这个问题是因为当我调用Class\u汽车时,来自Class\u目录的db混音了。 当我把Class\u目录放在Class\u汽车前面时,它就解决了,但我想知道如何正确地解决。你知道吗
更新:
多亏亚当·斯密才发现了这个问题。我得把这个文件改成pdo_mysql.py版本地址:
class Pdo_Mysql(object):
# all your existing definitions
def __new__(cls, *args, **kwargs):
**if not cls.__instance or not cls.__database:**
cls.__instance = super(Pdo_Mysql, cls).__new__(cls,*args,**kwargs)
return cls.__instance
这就是发生的事情。调用
class_automobile = Class_Automobile()
时,将创建一个新的Class_Automobile
实例,并对该实例调用__init__
方法。在__init__
内您正在呼叫Pdo_Mysql('host', 'user', 'password', 'db')
。Pdo_Mysql.__new__
被调用,Pdo\u Mysql作为cls变量,('host', 'user', 'password', 'db')
作为args
变量。因为这是第一次请求Pdo_Mysql
对象,所以类变量__instance
是None
,所以运行super
调用,并在Pdo_Mysql.__instance
变量上设置结果。这是班级作业。然后返回这个实例。如果你看看Python docs,你会发现:现在从
super __new__
调用中得到了Pdo_Mysql
的实例并返回它。将对它调用__init__
方法,并将args and kwargs
发送到__new__
。在__init__
中设置各种连接属性。你知道吗在这一点上一切都很好。如果您要调用您的
class_automobile
实例,它们将按您所期望的那样工作。让我们看看在创建下一个对象Class_Catalog
的实例时会发生什么。你知道吗它以与
Class_Automobile
相同的方式开始,直到我们到达self. __pdo_mysql_intern = Pdo_Mysql
调用。这次调用Pdo_Mysql.__new__
时,cls.__instance
变量被设置为Pdo_Mysql
的一个实例,这样就不会创建新的实例。但是您仍然从__new__
返回这个实例,因此__init__
方法仍然在这个实例上运行,但是使用了新的args and kwargs
。实例变量被设置为新值。所以现在实例class_automobile
和class_catalog
有一个__pdo_mysql_intern
变量指向同一个实例,并且该实例的主机、用户、密码和数据库都设置为初始化实例时使用的最后一个参数。你知道吗现在有一个可能的解决方案。。。你知道吗
似乎您正在尝试进行某种连接共享,这样就不会为每个连接到数据库的对象打开新的连接。但是,您只允许一个
Pdo_Mysql
实例存在。这意味着您不能连接到多个数据库并且只能作为单个用户。你知道吗您需要一个连接池(
Pdo_Mysql
对象)来选择,这样当您想连接到另一个db或作为不同的用户时,您就可以这样做。在Pdo_Mysql
类中,可以将__instance = None
变量更改为__instances = {}
。使用args
作为此字典的键,并更改__new__
方法以使用args
查找实例。请注意,这忽略了kwargs,我让您自己来决定如何包含它们(提示,不能将可变对象用作字典中的键)。您还需要将__initialized
变量添加到Pdo_Mysql
类中。将其默认为False
,并在__init__
中将其设置为True
。这是因为您可以确保在每个实例上只运行一次__init__
。你知道吗更进一步,我建议您不要使用
__new__
来创建单例,而是在pdo中创建一个helper方法_mysql.py版本叫get_conenction
什么的。让它使用相同的4个参数,它可以检查实例池中是否有匹配的实例,并返回现有连接或创建新连接。你知道吗相关问题 更多 >
编程相关推荐