day05


作業答疑

知識回顧

  • 反射
  • 裝飾器
  • 面向對象
  • 異常處理
  • 斷言

本節內容

  • 知識拾遺
  • 斷言
  • 三層架構
  • python mysql
  • socket

知識拾遺

1、什么是類?

2、什么是對象?

3、self是什么?

4、構造函數和析構函數

5、私有和公有

6、動態和靜態

7、特性

8、特殊的__init__方法和__call__方法

9、抽象

#抽象類、抽象方法
from abc import ABCMeta, abstractmethod
 
class Bar:
    __metaclass__ = ABCMeta
 
    @abstractmethod
    def Fun(self):pass
 
class Foo(Bar):
    def __init__(self):
        print '__init__'
        
Foo()
View Code

mysql

Linux

  • 安裝mysql: apt-get install mysql-server
  • 安裝python-mysql模塊:apt-get install python-mysqldb

Windows

  • 下載安裝mysql
  • python操作mysql模塊:MySQL-python-1.2.3.win32-py2.7.exe 或 MySQL-python-1.2.3.win-amd64-py2.7.exe
  • mysql圖形界面:Navicat_for_MySQL

安裝完成后,導入MySQLdb測試是否安裝成功

數據庫:

show databases;
use [databasename];
create database  [name];
View Code

數據表:

show tables;

create table students
    (
        id int  not null auto_increment primary key,
        name char(8) not null,
        sex char(4) not null,
        age tinyint unsigned not null,
        tel char(13) null default "-"
    );
View Code

增刪改查:

insert into students(name,sex,age,tel) values('alex','man',18,'151515151')

delete from students where id =2;

update students set name = 'sb' where id =1;

select * from students
View Code

MySQLdb

#!/usr/bin/env python
#coding:utf-8

import MySQLdb

'''
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')

cur = conn.cursor()

reCount = cur.execute('insert into UserInfo(Name,Address) values(%s,%s)',('alex','usa'))

conn.commit()

cur.close()
conn.close()

print reCount
'''

'''
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')

cur = conn.cursor()

reCount = cur.execute('delete from UserInfo')

conn.commit()

cur.close()

conn.close()

print reCount
'''

'''
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')
cur = conn.cursor()

li =[
     ('alex','usa'),
     ('sb','usa'),
]
reCount = cur.executemany('insert into UserInfo(Name,Address) values(%s,%s)',li)

conn.commit()
cur.close()
conn.close()

print reCount
'''

'''
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')
cur = conn.cursor()

reCount = cur.execute('update UserInfo set Name = %s',('alin',))

conn.commit()
cur.close()
conn.close()

print reCount
'''

'''
#fetchone/fetchmany(num)   
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')
cur = conn.cursor()

reCount = cur.execute('select * from UserInfo')

print cur.fetchone()
print cur.fetchone()
cur.scroll(-1,mode='relative')
print cur.fetchone()
print cur.fetchone()
cur.scroll(0,mode='absolute')
print cur.fetchone()
print cur.fetchone()

cur.close()
conn.close()

print reCount
'''

#fetchall

conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1234',db='07day05db')
#cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
cur = conn.cursor()

reCount = cur.execute('select Name,Address from UserInfo')

nRet = cur.fetchall()


cur.close()
conn.close()

print reCount
print nRet
for i in nRet:
    print i[0],i[1]
View Code

注意:cur.lastrowid

真實開發中的mysqlhelper怎么寫?

三層架構

socket

 什么是socket

  所謂socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄,應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。

  socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關閉close”模式來操作。Socket就是該模式的一個實現,socket即是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)

  例如:中國移動的客服

    對於移動來:一直在監聽一個號碼10086,當有電話進來后,就分配一個客服和客戶去溝通並處理請求

       對於用戶:需要知道10086這個號碼,並需要打通電話

import socket

ip_port = ('127.0.0.1',9999)

sk = socket.socket()
sk.bind(ip_port)
sk.listen(1)

while True:
    print 'waiting...'
    conn,addr =  sk.accept()
    conn.sendall('歡迎致電10086')
    conn.close()
server
import socket
ip_port = ('127.0.0.1',9999)

sk = socket.socket()
sk.connect(ip_port)

data  = sk.recv(1024)
sk.close()
print data
client
#!/usr/bin/env python
#coding:utf-8


import socket

ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
    conn,addr =  sk.accept()
    conn.sendall('歡迎致電 10086,請輸入1xxx,0轉人工服務.')
    Flag = True
    while Flag:
        data = conn.recv(1024)
        if data == 'exit':
            Flag = False
        elif data == '0':
            conn.sendall('通過可能會被錄音.balabala一大推')
        else:
            conn.sendall('請重新輸入.')
    conn.close()
10086 server
#!/usr/bin/env python
#coding:utf-8


import socket
import sys

ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port)

while True:

    data = sk.recv(1024)
    print data
    inp = raw_input('')
    sk.sendall(inp)
    if inp == 'exit':
        break
    
sk.close()
10086 client

sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)

參數一:地址簇

  socket.AF_INET IPv4(默認)
  socket.AF_INET6 IPv6

  socket.AF_UNIX 只能夠用於單一的Unix系統進程間通信

參數二:類型

  socket.SOCK_STREAM  流式socket , for TCP (默認)
  socket.SOCK_DGRAM   數據報式socket , for UDP

  socket.SOCK_RAW 原始套接字,普通的套接字無法處理ICMP、IGMP等網絡報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。
  socket.SOCK_RDM 是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在需要執行某些特殊操作時使用,如發送ICMP報文。SOCK_RAM通常僅限於高級用戶或管理員運行的程序使用。
  socket.SOCK_SEQPACKET 可靠的連續數據包服務

參數三:協議

  0  (默認)與特定的地址家族相關的協議,如果是 0 ,則系統就會根據地址格式和套接類別,自動選擇一個合適的協議

返回值:soket對象

import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
sk.bind(ip_port)

while True:
    data = sk.recv(1024)
    print data




import socket
ip_port = ('127.0.0.1',9999)

sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
while True:
    inp = raw_input('數據:').strip()
    if inp == 'exit':
        break
    sk.sendto(inp,ip_port)

sk.close()
udp

sk.bind(address)

  s.bind(address) 將套接字綁定到地址。address地址的格式取決於地址族。在AF_INET下,以元組(host,port)的形式表示地址。

sk.listen(backlog)

  開始監聽傳入連接。backlog指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少為1,大部分應用程序設為5就可以了。

sk.accept()

  接受連接並返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據。address是連接客戶端的地址。

  接收TCP 客戶的連接(阻塞式)等待連接的到來

sk.connect(address)

  連接到address處的套接字。一般,address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。

sk.connect_ex(address)

  同上,只不過會有返回值,連接成功時返回 0 ,連接失敗時候返回編碼,例如:10061

sk.close()

  關閉套接字

sk.recv(bufsize[,flag])

  接受套接字的數據。數據以字符串形式返回,bufsize指定要接收的最大數據量。flag提供有關消息的其他信息,通常可以忽略。

sk.recvfrom(bufsize[.flag])

  與recv()類似,但返回值是(data,address)。其中data是包含接收數據的字符串,address是發送數據的套接字地址。

sk.send(string[,flag])

  將string中的數據發送到連接的套接字。返回值是要發送的字節數量,該數量可能小於string的字節大小。

sk.sendall(string[,flag])

  將string中的數據發送到連接的套接字,但在返回之前會嘗試發送所有數據。成功返回None,失敗則拋出異常。

sk.sendto(string[,flag],address)

  將數據發送到套接字,address是形式為(ipaddr,port)的元組,指定遠程地址。返回值是發送的字節數。該函數主要用於UDP協議。

sk.settimeout(timeout)

  設置套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛創建套接字時設置,因為它們可能用於連接的操作(如connect())

sk.getpeername()

  返回連接套接字的遠程地址。返回值通常是元組(ipaddr,port)。

sk.getsockname()

  返回套接字自己的地址。通常是一個元組(ipaddr,port)

sk.fileno()

  套接字的文件描述符

socket應用場景:

#!/usr/bin/env python
#coding:utf-8
import socket

def handle_request(client):
    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n")
    client.send("Hello, Woddrld")

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8080))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':
  main()
Socket web

SocketServer

import SocketServer


class  MyServer(SocketServer.BaseRequestHandler):
    
    def setup(self):
        pass

    def handle(self):
        print self.request,self.client_address,self.server
        #self.request = socket
        #

    def finish(self):
        pass
        
if __name__ == '__main__':
    server = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
    server.serve_forever()
server
import socket

ip_port = ('127.0.0.1',9999)
while True:
    sk = socket.socket()
    sk.connect(ip_port)
    inp = raw_input('Data:')
    sk.sendall(inp)
    sk.close()
client

socket傳文件

#!/usr/bin/env python
#coding:utf-8

import SocketServer
import os

class MyServer(SocketServer.BaseRequestHandler):
    def handle(self):
        base_path = 'G:/temp'
        conn = self.request
        print 'connected...'
        while True:
            pre_data = conn.recv(1024)
            #獲取請求方法、文件名、文件大小
            cmd,file_name,file_size = pre_data.split('|')
            #已經接收文件的大小
            recv_size = 0
            #上傳文件路徑拼接
            file_dir = os.path.join(base_path,file_name)
            f = file(file_dir,'wb')
            Flag = True
            while Flag:
                #未上傳完畢,
                if int(file_size)>recv_size:
                    #最多接收1024,可能接收的小於1024
                    data = conn.recv(1024) 
                    recv_size+=len(data)
                #上傳完畢,則退出循環
                else:
                    recv_size = 0
                    Flag = False
                #寫入文件
                f.write(data)
            print 'upload successed.'
            f.close()
    
instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
instance.serve_forever()
server
#!/usr/bin/env python
#coding:utf-8


import socket
import sys
import os

ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port)

container = {'key':'','data':''}
while True:
    input = raw_input('path:')
    cmd,path = input.split('|') 
    file_name = os.path.basename(path)
    file_size=os.stat(path).st_size
    sk.send(cmd+"|"+file_name+'|'+str(file_size))
    send_size = 0
    f= file(path,'rb')
    Flag = True
    while Flag:
        if send_size + 1024 >file_size:
            data = f.read(file_size-send_size)
            Flag = False
        else:
            data = f.read(1024)
            send_size+=1024
        sk.send(data)
    f.close()
    
sk.close()
client

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM