python数据库连接类写其他类调用报超时_python面向对象,类,以及连接数据库
## 面向對象
### 1.面向對象三大特性: 封裝,繼承,多態
### 1.1.封裝
1.在類中對數據的賦值、內部調用對外部用戶是透明的
2.這使類變成了一個膠囊或容器,里面包含著類的數據和方法
3.作用
1)防止數據被隨意修改
2)使外部程序不需要關注對象內部的構造,只需要通過對外提供的接口進行直接訪問
## 2.繼承
### 2.1.單繼承
在程序中,繼承描述的是多個類之間的所屬關系。
如果一個類A里面的屬性和方法可以復用,則可以通過繼承的方式,傳遞到類B里。
那么類A就是基類,也叫做父類;類B就是派生類,也叫做子類。
### 2.2.多繼承
**子類從多個父類派生,而子類又沒有自己的構造函數時,**
**(1)按順序繼承,哪個父類在最前面且它又有自己的構造函數,就繼承它的構造函數;**
**(2)如果最前面第一個父類沒有構造函數,則繼承第2個的構造函數,第2個沒有的話,再往后找,以此類推。**
### 2.3.子類重寫父類的同名屬性和方法
#####?? 如果子類和父類的方法名和屬性名相同,則默認使用子類的? 叫 子類重寫父類的同名方法和屬性
### 2.4.子類調用父類方法
#####? 無論何時何地,self都表示是子類的對象。在調用父類方法時,通過傳遞self參數,來控制方法和屬性的訪問修改。
### 1.3. 多態(接口重用)
1.多態是面向對象的重要特性,簡單點說:“一個接口,多種實現”
2. 指一個基類中派生出了不同的子類,且每個子類在繼承同樣的方法名的同時又對父類的方法做了不同的實現
3. 這就是同一種事物表現出的多種形態
4. 比如黃種人繼承了人talk這個功能,但是他說的是中文,而美國人的talk是英文,但是他們是同樣的talk
***\*作用:\****簡單的講就是允許父類調用子類的方法
### 2.靜態方法、類方法、屬性方法? 魔法方法
### 1.靜態方法
1. 作用:靜態方法可以更好的組織代碼,防止代碼變大后變得比較混亂。
2. 特性:?靜態方法只是名義上歸類管理,實際上在靜態方法里訪問不了類或則實例中的任何屬性
3. 靜態方法使用場景:
1)我們要寫一個只在類中運行而不在實例中運行的方法.
2)經常有一些跟類有關系的功能但在運行時又不需要實例和類參與的情況下需要用到靜態方法.
3)比如更改環境變量或者修改其他類的屬性等能用到靜態方法.
4)這種情況可以直接用函數解決, 但這樣同樣會擴散類內部的代碼,造成維護困難.
4. 調用方式:?既可以被類直接調用,也可以通過實例調用
class aaa():
def__init__(self,name):
self.name = name
@staticmethod??????? #返回函數的靜態方法
def eee():
print("心如花木,向陽而生")
a = aaa
a.eee()????????????????? #方法1:使用實例調用
aaa.eee()??????????????? #方法2:使用類直接調用
返回結果:
心如花木,向陽而生
心如花木,向陽而生
### 2.類方法
1. 作用:無需實例化直接被類調用
2. 特性:?類方法只能訪問類變量,不能訪問實例變量
3. 類方法使用場景: 當我們還未創建實例,但是需要調用類中的方法
4. 調用方式:?既可以被類直接調用,也可以通過實例調用
class aaa():
name = '類變量'????? #在這里如果不定義類變量僅定義實例變量依然報錯
def__init__(self,name):
self.name = name??? #實例變量
@classmethod???#是用來指定一個類的方法為類方法
defeat(self,food):
print("%s is eating %s"%(self.name,food))
aaa.eat('baozi')????????? #方法1:使用類直接調用
d = aaa
d.eat("包子")??????????? #方法2:使用實例d調用
返回結果
類變量is eating baozi
類變量 is eating 包子
### 3. 屬性方法
作用:屬性方法把一個方法變成一個屬性,隱藏了實現細節,調用時不必加括號直接d.eat即可調用self.eat()方法
class aaa():
def__init__(self, name):
self.name = name
@property???????????? #@property是python的一種裝飾器,是用來修飾方法的。
defeat(self):
print(" %s在跳舞" % self.name)
d = aaa("1111111")
d.eat???????????????????? #不加()
# 調用會出以下錯誤, 說NoneType is not callable, 因為eat此時已經變成一個靜態屬性了,
# 不是方法了, 想調用已經不需要加()號了,直接d.eat就可以了
返回結果
1111111 在跳舞
### 4. 魔法方法
### 1._ _ _init_ _ _ 方法
在Python中定義類經常會用到__init__函數(方法),首先需要理解的是,兩個下劃線開頭的函數是聲明該屬性為私有,不能在類的外部被使用或訪問。而__init__函數(方法)支持帶參數類的初始化,也可為聲明該類的屬性(類中的變量)。__init__函數(方法)的第一個參數必須為self,后續參數為自己定義。
### 2. __ _str_ _ _方法
__str__方法是用來顯示信息的,通常是用來返回一個字符串,作為這個實例對象的描述信息,它只有一個參數,需要return一個數據,當你在類的外部打印實例對象的時候則會打印這個數據,在使用print(對象)或者str(對象)的時候會觸發此方法。
### 3._ __new_ _ _方法
大家剛才看到了這個__init__方法的效果,肯定都會認為這個方法是類中第一個執行的方法,其實并不然,我們的類最開始調用的是__new__方法,它的第一參數是它的類對象,其他的參數則是傳遞給__init__方法的,,_new__方法可以調用其他的類的方法或者返回別的實例來作為當前類的實例,所以如果__new__方法沒有返回實例,那么__init__方法就不會被調用,所以__new__方法決定了__init__方法是否使用,也可以說實例就是__new__方法創建的。__new__方法的主要用途是當你繼承了一些不可更改的屬性的時候,給你提供一個途徑去修改它。
### 4._ _call _ _方法
__call__方法可以是類的實例對象能像調用函數那樣使用對象。它的作用是簡化了對象下方法的使用,模糊了對象和函數調用時的區別。
### __5. _ _ dir _ ___方法
熟悉python的人都知道dir()方法可以讓我們查看當前環境下有些什么樣的方法和屬性可以使用,通過dir(object)可以獲得一個對象擁有的方法和屬性,同樣的道理,如果我們自己在類中定義了這個__dir__方法,我們就可以指定一些別人能夠被調用的方法,你的協同開發者就可以通過調用dir()方法查看到并使用。
### 1. PyMySQL介紹
PyMySQL
是在Python3.x版本中用于連接MySQL服務器的一個庫
### 2. PyMysql
使用流程

- pymysql
使用步驟:==核心類 Connect鏈接用? 和Cursor讀寫用==
1.與數據庫服務器建立鏈接
2.獲取游標對象 (用于發送和接收數據)
3.用游標執行sql語句
4.使用fetch方法來獲取執行的結果
5.關閉鏈接? 先關游標再關鏈接
==
連接數據庫注意事項==:
有一個MySQL數據庫,并且已經啟動。
有可以連接數據庫的用戶名和密碼。
有一個有權限操作的database。
### 3.引入模塊
在py文件中引入pymysql模塊
```python
from pymysql import *
### 4. Connection對象
用于建立與數據庫的連接
創建對象:調用connect()方法
```python
conn=connect(參數列表)
參數host:連接的mysql主機,如果本機是'localhost'
參數port:連接的mysql主機的端口,默認是3306
參數database:數據庫的名稱
參數user:連接的用戶名
參數password:連接的密碼
參數charset:通信采用的編碼方式,推薦使用utf8
####對象的方法
- close()
關閉連接
- commit()
提交
- cursor()
返回Cursor對象,用于執行sql語句并獲得結果
### 5. Cursor對象
用于執行sql語句,使用頻度最高的語句為select、insert、update、delete
獲取Cursor對象:調用Connection對象的cursor()方法
```python
cs1=conn.cursor()
####對象的方法
- close()關閉
- execute(operation [, parameters ])
執行語句,返回受影響的行數,主要用于執行insert、update、delete語句,也可以執行create、alter、drop等語句
- fetchone()執行查詢語句時,獲取查詢結果集的第一個行數據,返回一個元組
- fetchall()執行查詢時,獲取結果集的所有行,一行構成一個元組,再將這些元組裝入一個元組返回
####對象的屬性
- rowcount只讀屬性,表示最近一次execute()執行后受影響的行數
- connection獲得當前連接對象
### 6. ==單例模式==實現增刪改查
####準備數據
創建 "京東" 數據庫sql
create database jing_dong charset=utf8;
使用 "京東" 數據庫sql
use jing_dong;
創建一個商品goods數據表sql
create table goods(
id int unsigned primary keyauto_increment not null,
name varchar(150) not null,
cate_name varchar(40) not null,
brand_name varchar(40) notnull,
price decimal(10,3) not null default0,
is_show bit not null default 1,
is_saleoff bit not null default0
);
插入數據
```sql
insert into goods values(0,'r510vc 15.6
英寸筆記本','筆記本','華碩','3399',default,default);
insert into goods values(0,'y400n 14.0
英寸筆記本電腦','筆記本','聯想','4999',default,default);
insert into goods values(0,'g150th 15.6
英寸游戲本','游戲本','雷神','8499',default,default);
insert into goods values(0,'x550cc 15.6
英寸筆記本','筆記本','華碩','2799',default,default);
insert into goods values(0,'x240
超極本','超級本','聯想','4880',default,default);
insert into goods values(0,'u330p 13.3
英寸超極本','超級本','聯想','4299',default,default);
insert into goods values(0,'svp13226scb
觸控超極本','超級本','索尼','7999',default,default);
insert into goods values(0,'ipad mini 7.9
英寸平板電腦','平板電腦','蘋果','1998',default,default);
insert into goods values(0,'ipad air 9.7
英寸平板電腦','平板電腦','蘋果','3388',default,default);
insert into goods values(0,'ipad mini
配備 retina 顯示屏','平板電腦','蘋果','2788',default,default);
insert into goods values(0,'ideacentre c340 20
英寸一體電腦','臺式機','聯想','3499',default,default);
insert into goods values(0,'vostro 3800-r1206
臺式電腦','臺式機','戴爾','2899',default,default);
insert into goods values(0,'imac me086ch/a 21.5
英寸一體電腦','臺式機','蘋果','9188',default,default);
insert into goods values(0,'at7-7414lp
臺式電腦 linux )','臺式機','宏碁','3699',default,default);
insert into goods values(0,'z220sff f4f06pa
工作站','服務器/工作站','惠普','4288',default,default);
insert into goods values(0,'poweredge ii
服務器','服務器/工作站','戴爾','5388',default,default);
insert into goods values(0,'mac pro
專業級臺式電腦','服務器/工作站','蘋果','28888',default,default);
insert into goods values(0,'hmz-t3w
頭戴顯示設備','筆記本配件','索尼','6999',default,default);
insert into goods values(0,'
商務雙肩背包','筆記本配件','索尼','99',default,default);
insert into goods values(0,'x3250 m4
機架式服務器','服務器/工作站','ibm','6888',default,default);
insert into goods values(0,'
商務雙肩背包','筆記本配件','索尼','99',default,default);
#### pymysql交互
```python
import pymysql
class PyMysql(object):
__isinstance = None
def __new__(cls, *args,**kwargs):
if cls.__isinstance isNone:
cls.__isinstance =object.__new__(cls)
return cls.__isinstance
def __init__(self, database,host="localhost", port=3306, user="root",password="mysql", charset="utf8"):
連接數據庫
:param database:
數據庫名
:param host:
主機IP,默認本機
:param port:
主機端口,默認3306
:param user:
主機賬戶,默認root
:param password:
主機密碼,默認mysql
:param charset:
數據庫編碼,默認utf8
try:
self.db =pymysql.connect(host=host, port=port, user=user, password=password,database=database,
charset=charset)
self.cs =self.db.cursor()
except Exception as e:
print("
數據庫連接發生異常,詳細信息為:", e)
exit()
def query(self, sql):
查詢數據
:param sql:
查詢的sql語句
:return: None
try:
count =self.cs.execute(sql)
except Exception as e:
print("查詢失敗,詳細信息為:", e)
return
#查詢一行數據
# result =self.cs.fetchall()
#查詢多行數據
result = self.cs.fetchall()
if count != 0:
print("
共查到%d條數據:" % count)
for i in result:
print(i)
else:
print("沒有查到有效的數據")
def change_data(self, sql):
修改數據: 增、刪、改
:param sql:
:return:
#執行sql語句,并返回受影響的行數
try:
count = self.cs.execute(sql)
self.db.commit()
except Exception as e:
print("修改數據失敗,詳細信息為:", e)
else:
#提交之前的操作,如果之前已經之執行過多次的execute,那么就都進行提交
print("%d條數據被修改成功" % count)
def __del__(self):
self.db.close()
self.cs.close()
db = PyMysql("jing_dong")
db.query("select * from goods;")
### 7. sql注入
#### 1. SQL注入
SQL
注入是非常常見的一種網絡攻擊方式,主要是通過參數來讓 mysql 執行 sql 語句時進行預期之外的操作。
即:因為傳入的參數改變SQL的語義,變成了其他命令,從而操作了數據庫。
產生原因:SQL語句使用了動態拼接的方式。
例如,下面這段代碼通過獲取商品id為1的詳細信息:
```python
from pymysql import *
#創建Connection連接
conn = connect(host='localhost', port=3306, user='root', password='mysql',database='jing_dong', charset='utf8')
#獲得Cursor對象
cs1 = conn.cursor()
#利用字符串拼接,容易產生sql注入
qid = '1'
sql = 'select * from goods where id=' + qid +';'
# print(sql)
count = cs1.execute(sql)
result = cs1.fetchall()
for i in result:
print(i)
但是,如果傳入參數是:
```python
qid = "1 or 1=1"
你會發現,用戶能夠獲取所有商品信息,因為原本 sql 語句的判斷條件被 or 短路成為了永遠正確的語句。這里僅僅是舉一個例子,事實上,sql 注入的方式還有很多種,這里不深入介紹了。總之,只要是通過用戶輸入數據來拼接 sql 語句,就必須在第一時間考慮如何避免 SQL 注入問題。那么,如何防止 SQL 注入呢?
#### 2.預防 SQL 注入 – pymysql 參數化語句
pymysql的 execute 支持參數化 sql,通過占位符 %s 配合參數就可以實現 sql 注入問題的避免。
```python
import pymysql
#創建Connection連接
conn=connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
#獲得Cursor對象
cs1 = conn.cursor()
# sql語句的參數化,可以有效防止sql注入
sql = 'select * from goods where id=%s'
qid = '1'
count = cursor.execute(sql, qid)
result = cursor.fetchone()
print(result)
這樣參數化的方式,讓 mysql 通過預處理的方式避免了sql 注入的存在。
需要注意的是,不要因為參數是其他類型而換掉 %s,pymysql的占位符并不是 python 的通用占位符。
同時,也不要因為參數是 string 就在 %s 兩邊加引號,mysql 會自動去處理。
總結
以上是生活随笔為你收集整理的python数据库连接类写其他类调用报超时_python面向对象,类,以及连接数据库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三菱fx3uplc恢复出厂设置_三菱fx
- 下一篇: python ftplib模块_pyth