2014-12-06 76 views
2

下面是示例代碼,它提供了我希望獲得修復幫助的錯誤,或者瞭解更好的寫入方法。我有一個名爲mysql_connection的mysql「超級」類。在這個類中,連接到數據庫。我也有一些方法。簡單地運行「select version()」來顯示連接/查詢的工作原理。然後我有一個「chktable」方法,在這個例子中實例化一個名爲「table」的新子類,它繼承了超類。在實例化類之後,我調用了子類中的一個方法,該方法嘗試使用超類中的查詢方法來運行「show tables like'tbl name'」。這是我得到一個錯誤。Python使用超級類的mysql連接

import mysql.connector 
from mysql.connector import errorcode 
from mysql.connector.cursor import MySQLCursor 

class mysql_connection(object): 
    def __init__(self, **kwargs): 
     self.connection_options = {} 
     self.connection_options['user'] = 'root' 
     self.connection_options['password'] = '' 
     self.connection_options['host'] = '192.168.33.10' 
     self.connection_options['port'] = '3306' 
     self.connection_options['database'] = "test" 
     self.connection_options['raise_on_warnings'] = True 
     self.connect() 

    def connect(self): 
     try: 
      self.cnx = mysql.connector.connect(**self.connection_options) 
     except mysql.connector.Error as err: 
      if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: 
       print "Something is wrong with your user name or password" 
      elif err.errno == errorcode.ER_BAD_DB_ERROR: 
       print "Database does not exists" 
      else: 
       print err 

    def query(self, statement, data=''): 
     cursor = MySQLCursor(self.cnx) 
     cursor.execute(statement) 
     result = cursor.fetchall() 
     cursor.close 
     return result 

    def get_version(self): 
     print self.query("select version()") 

    def chktable(self, tb_name): 
     tab = table(name=tb_name) 
     tab.check_table() 

class table(mysql_connection): 
    def __init__(self, **kwargs): 
     self.name = kwargs['name'] 

    def check_table(self): 
     return super(table, self).query("show tables like '{}".format(self.name)) 

conn = mysql_connection() 
conn.get_version() 
conn.chktable("test") 

,我得到的錯誤是:

$ python example.py 
[(u'5.1.73',)] 
Traceback (most recent call last): 
    File "example.py", line 50, in <module> 
    conn.chktable("test") 
    File "example.py", line 39, in chktable 
    tab.check_table() 
    File "example.py", line 46, in check_table 
    return super(table, self).query("show tables like '{}".format(self.name)) 
    File "example.py", line 28, in query 
    cursor = MySQLCursor(self.cnx) 
    AttributeError: 'table' object has no attribute 'cnx' 

我不完全理解回調到超類,以及它如何與子類的作品,所以很可能我的問題。我也想知道是否有更好的方法來實現這一點。我想我可以完全擺脫子類,但我喜歡我創建的子類,所以我覺得應該有辦法解決它。我可以嘗試的第二件事是將子類放在主類中,但我認爲這不正確。

+1

爲什麼你的表從連接繼承? – jonrsharpe 2014-12-06 09:04:14

回答

2

正如喬恩指出的那樣,這不是繼承的恰當用法。這是爲了「是 - 一個」關係:即狗從動物繼承,因爲狗是動物。但是表格不是連接:表格可能使用連接,但這僅僅意味着您應該將連接的實例分配給表格中的實例變量。

另外,在繼承關係中,通常沒有什麼理由讓超類知道它的子類,就像在chktable方法中一樣。

(你看到實際的錯誤是因爲你沒有叫表的__init__超類的方法,但它更好地解決您的結構。)

+0

謝謝。你是正確的,它不是一個適當的繼承使用。儘管這只是一個例子,而且在實際代碼中mysql_connnection類的命名方式不同,我的類是「有」組合,而不是「是」。隨着對代碼的進一步思考,我意識到我不會在其他地方使用「擁有」類,所以我只是將它添加到主類中。我可能會去做一個實際的mysql連接組合類來從我正在處理的主要mysql類中解耦它。 – david 2014-12-07 15:43:38

+0

很好的解釋何時使用繼承以及如何處理這種情況,而不使用和實例變量 – 2016-06-07 23:21:23