Skip to content Skip to main navigation Skip to footer

python

python中DES和3DES加密算法实例

python中的des和3des加密算法是如何实现的呢?下面的内容将会通过具体的实例来演示python中DES和3DES加密算法的实现:

本文实例讲述了python实现的DES加密算法和3DES加密算法。分享给大家供大家参考。具体实现方法如下:

#############################################################################
# Documentation #
#############################################################################
# Author: Todd Whiteman
# Date: 16th March, 2009
# Verion: 2.0.0
# License: Public Domain – free to do as you wish
# Homepage: http://twhiteman.netfirms.com/des.html
#
# This is a pure python implementation of the DES encryption algorithm.
# It’s pure python to avoid portability issues, since most DES
# implementations are programmed in C (for performance reasons).
#
# Triple DES class is also implemented, utilising the DES base. Triple DES
# is either DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key.
#
# See the README.txt that should come with this python module for the
# implementation methods used.
#
# Thanks to:
# * David Broadwell for ideas, comments and suggestions.
# * Mario Wolff for pointing out and debugging some triple des CBC errors.
# * Santiago Palladino for providing the PKCS5 padding technique.
# * Shaya for correcting the PAD_PKCS5 triple des CBC errors.
#
“””A pure python implementation of the DES and TRIPLE DES encryption algorithms.
Class initialization
——————–
pyDes.des(key, [mode], [IV], [pad], [padmode])
pyDes.triple_des(key, [mode], [IV], [pad], [padmode])
key -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes
for Triple DES
mode -> Optional argument for encryption type, can be either
pyDes.ECB (Electronic Code Book) or pyDes.CBC (Cypher Block Chaining)
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
Length must be 8 bytes.
pad -> Optional argument, set the pad character (PAD_NORMAL) to use during
all encrypt/decrpt operations done with this instance.
padmode -> Optional argument, set the padding mode (PAD_NORMAL or PAD_PKCS5)
to use during all encrypt/decrpt operations done with this instance.
I recommend to use PAD_PKCS5 padding, as then you never need to worry about any
padding issues, as the padding can be removed unambiguously upon decrypting
data that was encrypted using PAD_PKCS5 padmode.
Common methods
————–
encrypt(data, [pad], [padmode])
decrypt(data, [pad], [padmode])
data -> Bytes to be encrypted/decrypted
pad -> Optional argument. Only when using padmode of PAD_NORMAL. For
encryption, adds this characters to the end of the data block when
data is not a multiple of 8 bytes. For decryption, will remove the
trailing characters that match this pad character from the last 8
bytes of the unencrypted data block.
padmode -> Optional argument, set the padding mode, must be one of PAD_NORMAL
or PAD_PKCS5). Defaults to PAD_NORMAL.
Example
——-
from pyDes import *
data = “Please encrypt my data”
k = des(“DESCRYPT”, CBC, “”, pad=None, padmode=PAD_PKCS5)
# For Python3, you’ll need to use bytes, i.e.:
# data = b”Please encrypt my data”
# k = des(b”DESCRYPT”, CBC, b””, pad=None, padmode=PAD_PKCS5)
d = k.encrypt(data)
print “Encrypted: %r” % d
print “Decrypted: %r” % k.decrypt(d)
assert k.decrypt(d, padmode=PAD_PKCS5) == data
See the module source (pyDes.py) for more examples of use.
You can also run the pyDes.py file without and arguments to see a simple test.
Note: This code was not written for high-end systems needing a fast
implementation, but rather a handy portable solution with small usage.
“””
import sys
# _pythonMajorVersion is used to handle Python2 and Python3 differences.
_pythonMajorVersion = sys.version_info[0] # Modes of crypting / cyphering
ECB = 0
CBC = 1
# Modes of padding
PAD_NORMAL = 1
PAD_PKCS5 = 2
# PAD_PKCS5: is a method that will unambiguously remove all padding
# characters after decryption, when originally encrypted with
# this padding mode.
# For a good description of the PKCS5 padding technique, see:
# http://www.faqs.org/rfcs/rfc1423.html
# The base class shared by des and triple des.
class _baseDes(object):
def __init__(self, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
if IV:
IV = self._guardAgainstUnicode(IV)
if pad:
pad = self._guardAgainstUnicode(pad)
self.block_size = 8
# Sanity checking of arguments.
if pad and padmode == PAD_PKCS5:
raise ValueError(“Cannot use a pad character with PAD_PKCS5”)
if IV and len(IV) != self.block_size:
raise ValueError(“Invalid Initial Value (IV), must be a multiple of ” + str(self.block_size) + ” bytes”)
# Set the passed in variables
self._mode = mode
self._iv = IV
self._padding = pad
self._padmode = padmode
def getKey(self):
“””getKey() -> bytes”””
return self.__key
def setKey(self, key):
“””Will set the crypting key for this object.”””
key = self._guardAgainstUnicode(key)
self.__key = key
def getMode(self):
“””getMode() -> pyDes.ECB or pyDes.CBC”””
return self._mode
def setMode(self, mode):
“””Sets the type of crypting mode, pyDes.ECB or pyDes.CBC”””
self._mode = mode
def getPadding(self):
“””getPadding() -> bytes of length 1. Padding character.”””
return self._padding
def setPadding(self, pad):
“””setPadding() -> bytes of length 1. Padding character.”””
if pad is not None:
pad = self._guardAgainstUnicode(pad)
self._padding = pad
def getPadMode(self):
“””getPadMode() -> pyDes.PAD_NORMAL or pyDes.PAD_PKCS5″””
return self._padmode
def setPadMode(self, mode):
“””Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5″””
self._padmode = mode
def getIV(self):
“””getIV() -> bytes”””
return self._iv
def setIV(self, IV):
“””Will set the Initial Value, used in conjunction with CBC mode”””
if not IV or len(IV) != self.block_size:
raise ValueError(“Invalid Initial Value (IV), must be a multiple of ” + str(self.block_size) + ” bytes”)
IV = self._guardAgainstUnicode(IV)
self._iv = IV
def _padData(self, data, pad, padmode):
# Pad data depending on the mode
if padmode is None:
# Get the default padding mode.
padmode = self.getPadMode()
if pad and padmode == PAD_PKCS5:
raise ValueError(“Cannot use a pad character with PAD_PKCS5”)
if padmode == PAD_NORMAL:
if len(data) % self.block_size == 0:
# No padding required.
return data
if not pad:
# Get the default padding.
pad = self.getPadding()
if not pad:
raise ValueError(“Data must be a multiple of ” + str(self.block_size) + ” bytes in length. Use padmode=PAD_PKCS5 or set the pad character.”)
data += (self.block_size – (len(data) % self.block_size)) * pad
elif padmode == PAD_PKCS5:
pad_len = 8 – (len(data) % self.block_size)
if _pythonMajorVersion < 3: data += pad_len * chr(pad_len) else: data += bytes([pad_len] * pad_len) return data def _unpadData(self, data, pad, padmode): # Unpad data depending on the mode. if not data: return data if pad and padmode == PAD_PKCS5: raise ValueError("Cannot use a pad character with PAD_PKCS5") if padmode is None: # Get the default padding mode. padmode = self.getPadMode() if padmode == PAD_NORMAL: if not pad: # Get the default padding. pad = self.getPadding() if pad: data = data[:-self.block_size] + data[-self.block_size:].rstrip(pad) elif padmode == PAD_PKCS5: if _pythonMajorVersion < 3: pad_len = ord(data[-1]) else: pad_len = data[-1] data = data[:-pad_len] return data def _guardAgainstUnicode(self, data): # Only accept byte strings or ascii unicode values, otherwise # there is no way to correctly decode the data into bytes. if _pythonMajorVersion < 3: if isinstance(data, unicode): raise ValueError("pyDes can only work with bytes, not Unicode strings.") else: if isinstance(data, str): # Only accept ascii unicode values. try: return data.encode('ascii') except UnicodeEncodeError: pass raise ValueError("pyDes can only work with encoded strings, not Unicode.") return data ############################################################################# # DES # ############################################################################# class des(_baseDes): """DES encryption/decrytpion class Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes. pyDes.des(key,[mode], [IV]) key -> Bytes containing the encryption key, must be exactly 8 bytes
mode -> Optional argument for encryption type, can be either pyDes.ECB
(Electronic Code Book), pyDes.CBC (Cypher Block Chaining)
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
Must be 8 bytes in length.
pad -> Optional argument, set the pad character (PAD_NORMAL) to use
during all encrypt/decrpt operations done with this instance.
padmode -> Optional argument, set the padding mode (PAD_NORMAL or
PAD_PKCS5) to use during all encrypt/decrpt operations done
with this instance.
“””
# Permutation and translation tables for DES
__pc1 = [56, 48, 40, 32, 24, 16, 8,
, 57, 49, 41, 33, 25, 17,
, 1, 58, 50, 42, 34, 26,
, 10, 2, 59, 51, 43, 35,
, 54, 46, 38, 30, 22, 14,
, 61, 53, 45, 37, 29, 21,
, 5, 60, 52, 44, 36, 28,
, 12, 4, 27, 19, 11, 3
] # number left rotations of pc1
__left_rotations = [
, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
] # permuted choice key (table 2)
__pc2 = [
, 16, 10, 23, 0, 4,
, 27, 14, 5, 20, 9,
, 18, 11, 3, 25, 7,
, 6, 26, 19, 12, 1,
, 51, 30, 36, 46, 54,
, 39, 50, 44, 32, 47,
, 48, 38, 55, 33, 52,
, 41, 49, 35, 28, 31
] # initial permutation IP
__ip = [57, 49, 41, 33, 25, 17, 9, 1,
, 51, 43, 35, 27, 19, 11, 3,
, 53, 45, 37, 29, 21, 13, 5,
, 55, 47, 39, 31, 23, 15, 7,
, 48, 40, 32, 24, 16, 8, 0,
, 50, 42, 34, 26, 18, 10, 2,
, 52, 44, 36, 28, 20, 12, 4,
, 54, 46, 38, 30, 22, 14, 6
] # Expansion table for turning 32 bit blocks into 48 bits
__expansion_table = [
, 0, 1, 2, 3, 4,
, 4, 5, 6, 7, 8,
, 8, 9, 10, 11, 12,
, 12, 13, 14, 15, 16,
, 16, 17, 18, 19, 20,
, 20, 21, 22, 23, 24,
, 24, 25, 26, 27, 28,
, 28, 29, 30, 31, 0
] # The (in)famous S-boxes
__sbox = [
# S1
[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
# S2
[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
# S3
[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
# S4
[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
# S5
[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
# S6
[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
# S7
[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
# S8
[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],
] # 32-bit permutation function P used on the output of the S-boxes
__p = [
, 6, 19, 20, 28, 11,
, 16, 0, 14, 22, 25,
, 17, 30, 9, 1, 7,
,13, 31, 26, 2, 8,
, 12, 29, 5, 21, 10,
, 24
] # final permutation IP^-1
__fp = [
, 7, 47, 15, 55, 23, 63, 31,
, 6, 46, 14, 54, 22, 62, 30,
, 5, 45, 13, 53, 21, 61, 29,
, 4, 44, 12, 52, 20, 60, 28,
, 3, 43, 11, 51, 19, 59, 27,
, 2, 42, 10, 50, 18, 58, 26,
, 1, 41, 9, 49, 17, 57, 25,
, 0, 40, 8, 48, 16, 56, 24
] # Type of crypting being done
ENCRYPT = 0x00
DECRYPT = 0x01
# Initialisation
def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
# Sanity checking of arguments.
if len(key) != 8:
raise ValueError(“Invalid DES key size. Key must be exactly 8 bytes long.”)
_baseDes.__init__(self, mode, IV, pad, padmode)
self.key_size = 8
self.L = [] self.R = [] self.Kn = [ [0] * 48 ] * 16 # 16 48-bit keys (K1 – K16)
self.final = [] self.setKey(key)
def setKey(self, key):
“””Will set the crypting key for this object. Must be 8 bytes.”””
_baseDes.setKey(self, key)
self.__create_sub_keys()
def __String_to_BitList(self, data):
“””Turn the string data, into a list of bits (1, 0)’s”””
if _pythonMajorVersion < 3: # Turn the strings into integers. Python 3 uses a bytes # class, which already has this behaviour. data = [ord(c) for c in data] l = len(data) * 8 result = [0] * l pos = 0 for ch in data: i = 7 while i >= 0:
if ch & (1 << i) != 0: result[pos] = 1 else: result[pos] = 0 pos += 1 i -= 1 return result def __BitList_to_String(self, data): """Turn the list of bits -> data, into a string”””
result = [] pos = 0
c = 0
while pos < len(data): c += data[pos] << (7 - (pos % 8)) if (pos % 8) == 7: result.append(c) c = 0 pos += 1 if _pythonMajorVersion < 3: return ''.join([ chr(c) for c in result ]) else: return bytes(result) def __permutate(self, table, block): """Permutate this block with the specified table""" return list(map(lambda x: block[x], table)) # Transform the secret key, so that it is ready for data processing # Create the 16 subkeys, K[1] - K[16] def __create_sub_keys(self): """Create the 16 subkeys K[1] to K[16] from the given key""" key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey())) i = 0 # Split into Left and Right sections self.L = key[:28] self.R = key[28:] while i < 16: j = 0 # Perform circular left shifts while j < des.__left_rotations[i]: self.L.append(self.L[0]) del self.L[0] self.R.append(self.R[0]) del self.R[0] j += 1 # Create one of the 16 subkeys through pc2 permutation self.Kn[i] = self.__permutate(des.__pc2, self.L + self.R) i += 1 # Main part of the encryption algorithm, the number cruncher 🙂 def __des_crypt(self, block, crypt_type): """Crypt the block of data through DES bit-manipulation""" block = self.__permutate(des.__ip, block) self.L = block[:32] self.R = block[32:] # Encryption starts from Kn[1] through to Kn[16] if crypt_type == des.ENCRYPT: iteration = 0 iteration_adjustment = 1 # Decryption starts from Kn[16] down to Kn[1] else: iteration = 15 iteration_adjustment = -1 i = 0 while i < 16: # Make a copy of R[i-1], this will later become L[i] tempR = self.R[:] # Permutate R[i - 1] to start creating R[i] self.R = self.__permutate(des.__expansion_table, self.R) # Exclusive or R[i - 1] with K[i], create B[1] to B[8] whilst here self.R = list(map(lambda x, y: x ^ y, self.R, self.Kn[iteration])) B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] # Optimization: Replaced below commented code with above #j = 0 #B = [] #while j < len(self.R): # self.R[j] = self.R[j] ^ self.Kn[iteration][j] # j += 1 # if j % 6 == 0: # B.append(self.R[j-6:j]) # Permutate B[1] to B[8] using the S-Boxes j = 0 Bn = [0] * 32 pos = 0 while j < 8: # Work out the offsets m = (B[j][0] << 1) + B[j][5] n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4] # Find the permutation value v = des.__sbox[j][(m << 4) + n] # Turn value into bits, add it to result: Bn Bn[pos] = (v & 8) >> 3
Bn[pos + 1] = (v & 4) >> 2
Bn[pos + 2] = (v & 2) >> 1
Bn[pos + 3] = v & 1
pos += 4
j += 1
# Permutate the concatination of B[1] to B[8] (Bn)
self.R = self.__permutate(des.__p, Bn)
# Xor with L[i – 1] self.R = list(map(lambda x, y: x ^ y, self.R, self.L))
# Optimization: This now replaces the below commented code
#j = 0
#while j < len(self.R): # self.R[j] = self.R[j] ^ self.L[j] # j += 1 # L[i] becomes R[i - 1] self.L = tempR i += 1 iteration += iteration_adjustment # Final permutation of R[16]L[16] self.final = self.__permutate(des.__fp, self.R + self.L) return self.final # Data to be encrypted/decrypted def crypt(self, data, crypt_type): """Crypt the data in blocks, running it through des_crypt()""" # Error check the data if not data: return '' if len(data) % self.block_size != 0: if crypt_type == des.DECRYPT: # Decryption must work on 8 byte blocks raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytesn.") if not self.getPadding(): raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytesn. Try setting the optional padding character") else: data += (self.block_size - (len(data) % self.block_size)) * self.getPadding() # print "Len of data: %f" % (len(data) / self.block_size) if self.getMode() == CBC: if self.getIV(): iv = self.__String_to_BitList(self.getIV()) else: raise ValueError("For CBC mode, you must supply the Initial Value (IV) for ciphering") # Split the data into blocks, crypting each one seperately i = 0 dict = {} result = [] #cached = 0 #lines = 0 while i < len(data): # Test code for caching encryption results #lines += 1 #if dict.has_key(data[i:i+8]): #print "Cached result for: %s" % data[i:i+8] # cached += 1 # result.append(dict[data[i:i+8]]) # i += 8 # continue block = self.__String_to_BitList(data[i:i+8]) # Xor with IV if using CBC mode if self.getMode() == CBC: if crypt_type == des.ENCRYPT: block = list(map(lambda x, y: x ^ y, block, iv)) #j = 0 #while j < len(block): # block[j] = block[j] ^ iv[j] # j += 1 processed_block = self.__des_crypt(block, crypt_type) if crypt_type == des.DECRYPT: processed_block = list(map(lambda x, y: x ^ y, processed_block, iv)) #j = 0 #while j < len(processed_block): # processed_block[j] = processed_block[j] ^ iv[j] # j += 1 iv = block else: iv = processed_block else: processed_block = self.__des_crypt(block, crypt_type) # Add the resulting crypted block to our list #d = self.__BitList_to_String(processed_block) #result.append(d) result.append(self.__BitList_to_String(processed_block)) #dict[data[i:i+8]] = d i += 8 # print "Lines: %d, cached: %d" % (lines, cached) # Return the full crypted string if _pythonMajorVersion < 3: return ''.join(result) else: return bytes.fromhex('').join(result) def encrypt(self, data, pad=None, padmode=None): """encrypt(data, [pad], [padmode]) -> bytes
data : Bytes to be encrypted
pad : Optional argument for encryption padding. Must only be one byte
padmode : Optional argument for overriding the padding mode.
The data must be a multiple of 8 bytes and will be encrypted
with the already specified key. Data does not have to be a
multiple of 8 bytes if the padding character is supplied, or
the padmode is set to PAD_PKCS5, as bytes will then added to
ensure the be padded data is a multiple of 8 bytes.
“””
data = self._guardAgainstUnicode(data)
if pad is not None:
pad = self._guardAgainstUnicode(pad)
data = self._padData(data, pad, padmode)
return self.crypt(data, des.ENCRYPT)
def decrypt(self, data, pad=None, padmode=None):
“””decrypt(data, [pad], [padmode]) -> bytes
data : Bytes to be encrypted
pad : Optional argument for decryption padding. Must only be one byte
padmode : Optional argument for overriding the padding mode.
The data must be a multiple of 8 bytes and will be decrypted
with the already specified key. In PAD_NORMAL mode, if the
optional padding character is supplied, then the un-encrypted
data will have the padding characters removed from the end of
the bytes. This pad removal only occurs on the last 8 bytes of
the data (last data block). In PAD_PKCS5 mode, the special
padding end markers will be removed from the data after decrypting.
“””
data = self._guardAgainstUnicode(data)
if pad is not None:
pad = self._guardAgainstUnicode(pad)
data = self.crypt(data, des.DECRYPT)
return self._unpadData(data, pad, padmode)
#############################################################################
# Triple DES #
#############################################################################
class triple_des(_baseDes):
“””Triple DES encryption/decrytpion class
This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or
the DES-EDE2 (when a 16 byte key is supplied) encryption methods.
Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes.
pyDes.des(key, [mode], [IV])
key -> Bytes containing the encryption key, must be either 16 or
bytes long
mode -> Optional argument for encryption type, can be either pyDes.ECB
(Electronic Code Book), pyDes.CBC (Cypher Block Chaining)
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
Must be 8 bytes in length.
pad -> Optional argument, set the pad character (PAD_NORMAL) to use
during all encrypt/decrpt operations done with this instance.
padmode -> Optional argument, set the padding mode (PAD_NORMAL or
PAD_PKCS5) to use during all encrypt/decrpt operations done
with this instance.
“””
def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
_baseDes.__init__(self, mode, IV, pad, padmode)
self.setKey(key)
def setKey(self, key):
“””Will set the crypting key for this object. Either 16 or 24 bytes long.”””
self.key_size = 24 # Use DES-EDE3 mode
if len(key) != self.key_size:
if len(key) == 16: # Use DES-EDE2 mode
self.key_size = 16
else:
raise ValueError(“Invalid triple DES key size. Key must be either 16 or 24 bytes long”)
if self.getMode() == CBC:
if not self.getIV():
# Use the first 8 bytes of the key
self._iv = key[:self.block_size] if len(self.getIV()) != self.block_size:
raise ValueError(“Invalid IV, must be 8 bytes in length”)
self.__key1 = des(key[:8], self._mode, self._iv,
self._padding, self._padmode)
self.__key2 = des(key[8:16], self._mode, self._iv,
self._padding, self._padmode)
if self.key_size == 16:
self.__key3 = self.__key1
else:
self.__key3 = des(key[16:], self._mode, self._iv,
self._padding, self._padmode)
_baseDes.setKey(self, key)
# Override setter methods to work on all 3 keys.
def setMode(self, mode):
“””Sets the type of crypting mode, pyDes.ECB or pyDes.CBC”””
_baseDes.setMode(self, mode)
for key in (self.__key1, self.__key2, self.__key3):
key.setMode(mode)
def setPadding(self, pad):
“””setPadding() -> bytes of length 1. Padding character.”””
_baseDes.setPadding(self, pad)
for key in (self.__key1, self.__key2, self.__key3):
key.setPadding(pad)
def setPadMode(self, mode):
“””Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5″””
_baseDes.setPadMode(self, mode)
for key in (self.__key1, self.__key2, self.__key3):
key.setPadMode(mode)
def setIV(self, IV):
“””Will set the Initial Value, used in conjunction with CBC mode”””
_baseDes.setIV(self, IV)
for key in (self.__key1, self.__key2, self.__key3):
key.setIV(IV)
def encrypt(self, data, pad=None, padmode=None):
“””encrypt(data, [pad], [padmode]) -> bytes
data : bytes to be encrypted
pad : Optional argument for encryption padding. Must only be one byte
padmode : Optional argument for overriding the padding mode.
The data must be a multiple of 8 bytes and will be encrypted
with the already specified key. Data does not have to be a
multiple of 8 bytes if the padding character is supplied, or
the padmode is set to PAD_PKCS5, as bytes will then added to
ensure the be padded data is a multiple of 8 bytes.
“””
ENCRYPT = des.ENCRYPT
DECRYPT = des.DECRYPT
data = self._guardAgainstUnicode(data)
if pad is not None:
pad = self._guardAgainstUnicode(pad)
# Pad the data accordingly.
data = self._padData(data, pad, padmode)
if self.getMode() == CBC:
self.__key1.setIV(self.getIV())
self.__key2.setIV(self.getIV())
self.__key3.setIV(self.getIV())
i = 0
result = [] while i < len(data): block = self.__key1.crypt(data[i:i+8], ENCRYPT) block = self.__key2.crypt(block, DECRYPT) block = self.__key3.crypt(block, ENCRYPT) self.__key1.setIV(block) self.__key2.setIV(block) self.__key3.setIV(block) result.append(block) i += 8 if _pythonMajorVersion < 3: return ''.join(result) else: return bytes.fromhex('').join(result) else: data = self.__key1.crypt(data, ENCRYPT) data = self.__key2.crypt(data, DECRYPT) return self.__key3.crypt(data, ENCRYPT) def decrypt(self, data, pad=None, padmode=None): """decrypt(data, [pad], [padmode]) -> bytes
data : bytes to be encrypted
pad : Optional argument for decryption padding. Must only be one byte
padmode : Optional argument for overriding the padding mode.
The data must be a multiple of 8 bytes and will be decrypted
with the already specified key. In PAD_NORMAL mode, if the
optional padding character is supplied, then the un-encrypted
data will have the padding characters removed from the end of
the bytes. This pad removal only occurs on the last 8 bytes of
the data (last data block). In PAD_PKCS5 mode, the special
padding end markers will be removed from the data after
decrypting, no pad character is required for PAD_PKCS5.
“””
ENCRYPT = des.ENCRYPT
DECRYPT = des.DECRYPT
data = self._guardAgainstUnicode(data)
if pad is not None:
pad = self._guardAgainstUnicode(pad)
if self.getMode() == CBC:
self.__key1.setIV(self.getIV())
self.__key2.setIV(self.getIV())
self.__key3.setIV(self.getIV())
i = 0
result = [] while i < len(data): iv = data[i:i+8] block = self.__key3.crypt(iv, DECRYPT) block = self.__key2.crypt(block, ENCRYPT) block = self.__key1.crypt(block, DECRYPT) self.__key1.setIV(iv) self.__key2.setIV(iv) self.__key3.setIV(iv) result.append(block) i += 8 if _pythonMajorVersion < 3: data = ''.join(result) else: data = bytes.fromhex('').join(result) else: data = self.__key3.crypt(data, DECRYPT) data = self.__key2.crypt(data, ENCRYPT) data = self.__key1.crypt(data, DECRYPT) return self._unpadData(data, pad, padmode) [/code]
python中DES和3DES加密算法实例就是这样,欢迎大家参考。。。。

python中实现对FTP服务器上传下载文件目录的方法

python中如何从ftp服务器上下载文件或目录,如何上传文件或目录到FTP server上呢?下面的内容将会通过创建一个新的类来演示如何来实现对FTP目录或文件的上传和下载:

本文实例讲述了python实现支持目录FTP上传下载文件的方法。分享给大家供大家参考。具体如下:

该程序支持ftp上传下载文件和目录、适用于windows和linux平台。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ftplib
import os
import sys
class FTPSync(object):
  conn = ftplib.FTP()
  def __init__(self,host,port=21):
    self.conn.connect(host,port)
  def login(self,username,password):
    self.conn.login(username,password)
    self.conn.set_pasv(False)
    print self.conn.welcome
  def test(self,ftp_path):
    print ftp_path
    print self._is_ftp_dir(ftp_path)
    #print self.conn.nlst(ftp_path)
    #self.conn.retrlines( 'LIST ./a/b')
    #ftp_parent_path = os.path.dirname(ftp_path)
    #ftp_dir_name = os.path.basename(ftp_path)
    #print ftp_parent_path
    #print ftp_dir_name
  def _is_ftp_file(self,ftp_path):
    try:
      if ftp_path in self.conn.nlst(os.path.dirname(ftp_path)):
        return True
      else:
        return False
    except ftplib.error_perm,e:
      return False
  def _ftp_list(self, line):
    list = line.split(' ')
    if self.ftp_dir_name==list[-1] and list[0].startswith('d'):
      self._is_dir = True
  def _is_ftp_dir(self,ftp_path):
    ftp_path = ftp_path.rstrip('/')
    ftp_parent_path = os.path.dirname(ftp_path)
    self.ftp_dir_name = os.path.basename(ftp_path)
    self._is_dir = False
    if ftp_path == '.' or ftp_path== './' or ftp_path=='':
      self._is_dir = True
    else:
      #this ues callback function ,that will change _is_dir value
      try:
        self.conn.retrlines('LIST %s' %ftp_parent_path,self._ftp_list)
      except ftplib.error_perm,e:
        return self._is_dir
    return self._is_dir
  def get_file(self,ftp_path,local_path='.'):
    ftp_path = ftp_path.rstrip('/')
    if self._is_ftp_file(ftp_path):
      file_name = os.path.basename(ftp_path)
      #如果本地路径是目录,下载文件到该目录
      if os.path.isdir(local_path):
        file_handler = open(os.path.join(local_path,file_name), 'wb' )
        self.conn.retrbinary("RETR %s" %(ftp_path), file_handler.write)
        file_handler.close()
      #如果本地路径不是目录,但上层目录存在,则按照本地路径的文件名作为下载的文件名称
      elif os.path.isdir(os.path.dirname(local_path)):
        file_handler = open(local_path, 'wb' )
        self.conn.retrbinary("RETR %s" %(ftp_path), file_handler.write)
        file_handler.close()
      #如果本地路径不是目录,且上层目录不存在,则退出
      else:
        print 'EROOR:The dir:%s is not exist' %os.path.dirname(local_path)
    else:
      print 'EROOR:The ftp file:%s is not exist' %ftp_path
  def put_file(self,local_path,ftp_path='.'):
    ftp_path = ftp_path.rstrip('/')
    if os.path.isfile( local_path ):
      file_handler = open(local_path, "r")
      local_file_name = os.path.basename(local_path)
      #如果远程路径是个目录,则上传文件到这个目录,文件名不变
      if self._is_ftp_dir(ftp_path):
        self.conn.storbinary('STOR %s'%os.path.join(ftp_path,local_file_name), file_handler)
      #如果远程路径的上层是个目录,则上传文件,文件名按照给定命名
      elif self._is_ftp_dir(os.path.dirname(ftp_path)):
        print 'STOR %s'%ftp_path
        self.conn.storbinary('STOR %s'%ftp_path, file_handler)
      #如果远程路径不是目录,且上一层的目录也不存在,则提示给定远程路径错误
      else:
        print 'EROOR:The ftp path:%s is error' %ftp_path
      file_handler.close()
    else:
      print 'ERROR:The file:%s is not exist' %local_path
  def get_dir(self,ftp_path,local_path='.',begin=True):
    ftp_path = ftp_path.rstrip('/')
    #当ftp目录存在时下载
    if self._is_ftp_dir(ftp_path):
      #如果下载到本地当前目录下,并创建目录
      #下载初始化:如果给定的本地路径不存在需要创建,同时将ftp的目录存放在给定的本地目录下。
      #ftp目录下文件存放的路径为local_path=local_path+os.path.basename(ftp_path)
      #例如:将ftp文件夹a下载到本地的a/b目录下,则ftp的a目录下的文件将下载到本地的a/b/a目录下
      if begin:
        if not os.path.isdir(local_path):
          os.makedirs(local_path)
        local_path=os.path.join(local_path,os.path.basename(ftp_path))
      #如果本地目录不存在,则创建目录
      if not os.path.isdir(local_path):
        os.makedirs(local_path)
      #进入ftp目录,开始递归查询
      self.conn.cwd(ftp_path)
      ftp_files = self.conn.nlst()
      for file in ftp_files:
        local_file = os.path.join(local_path, file)
        #如果file ftp路径是目录则递归上传目录(不需要再进行初始化begin的标志修改为False)
        #如果file ftp路径是文件则直接上传文件
        if self._is_ftp_dir(file):
          self.get_dir(file,local_file,False)
        else:
          self.get_file(file,local_file)
      #如果当前ftp目录文件已经遍历完毕返回上一层目录
      self.conn.cwd( ".." )
      return
    else:
      print 'ERROR:The dir:%s is not exist' %ftp_path
      return
  def put_dir(self,local_path,ftp_path='.',begin=True):
    ftp_path = ftp_path.rstrip('/')
    #当本地目录存在时上传
    if os.path.isdir(local_path):
      #上传初始化:如果给定的ftp路径不存在需要创建,同时将本地的目录存放在给定的ftp目录下。
      #本地目录下文件存放的路径为ftp_path=ftp_path+os.path.basename(local_path)
      #例如:将本地文件夹a上传到ftp的a/b目录下,则本地a目录下的文件将上传的ftp的a/b/a目录下
      if begin:
        if not self._is_ftp_dir(ftp_path):
          self.conn.mkd(ftp_path)
        ftp_path=os.path.join(ftp_path,os.path.basename(local_path))
      #如果ftp路径不是目录,则创建目录
      if not self._is_ftp_dir(ftp_path):
        self.conn.mkd(ftp_path)
      #进入本地目录,开始递归查询
      os.chdir(local_path)
      local_files = os.listdir('.')
      for file in local_files:
        #如果file本地路径是目录则递归上传目录(不需要再进行初始化begin的标志修改为False)
        #如果file本地路径是文件则直接上传文件
        if os.path.isdir(file):
          ftp_path=os.path.join(ftp_path,file)
          self.put_dir(file,ftp_path,False)
        else:
          self.put_file(file,ftp_path)
      #如果当前本地目录文件已经遍历完毕返回上一层目录
      os.chdir( ".." )
    else:
      print 'ERROR:The dir:%s is not exist' %local_path
      return
if __name__ == '__main__':
  ftp = FTPSync('192.168.1.110')
  ftp.login('test','test')
  #上传文件,不重命名
  #ftp.put_file('111.txt','a/b')
  #上传文件,重命名
  #ftp.put_file('111.txt','a/112.txt')
  #下载文件,不重命名
  #ftp.get_file('/a/111.txt',r'D:\')
  #下载文件,重命名
  #ftp.get_file('/a/111.txt',r'D:112.txt')
  #下载到已经存在的文件夹
  #ftp.get_dir('a/b/c',r'D:\a')
  #下载到不存在的文件夹
  #ftp.get_dir('a/b/c',r'D:\aa')
  #上传到已经存在的文件夹
  ftp.put_dir('b','a')
  #上传到不存在的文件夹
  ftp.put_dir('b','aa/B/')
 


python中实现对FTP服务器上传下载文件目录的方法就是这样,欢迎大家参考。。。。

python中守护进程的用法解析

python中守护进程是什么?如何创建一个守护进程?下面会通过详细的实例来介绍python中守护进程的用法:

本文实例讲述了Python守护进程用法。分享给大家供大家参考。具体分析如下:

守护进程是可以一直运行而不阻塞主程序退出。要标志一个守护进程,可以将Process实例的daemon属性设置为True。代码如下:

import os
import time
import random
import sys
from multiprocessing import Process,current_process
def daemon():
    p = current_process()
    print "starting ID%d prccess%sn" % (p.pid,p.name)
    sys.stdout.flush()
    time.sleep(3)
    print "Exiting:%sn" % p.name
    sys.stdout.flush()
def main():
    p = Process(name="Daemon",target=daemon)
    p.daemon=True
    p.start()
if __name__=="__main__":
    main()
    time.sleep(1)
 

由于主进程会在1秒后退出,守护进程的 print “Exiting:%sn” % p.name这句是看不到的。

若想看到守护进程的 print “Exiting:%sn” % p.name语句输出,可以利用join,主进程等待守护进程的退出后再退出,即在,p.start()后添加p.join()然后把time。sleep(1)删除


python中守护进程的用法就是这样,欢迎大家参考。。。。

python通过select模块实现异步IO的方法

python如何通过select模块实现异步IO的方法?下面会通过详细的实例来介绍通过select模块实现异步IO的方法:

本文实例讲述了Python通过select实现异步IO的方法。分享给大家供大家参考。具体如下:

在Python中使用select与poll比起在C中使用简单得多。select函数的参数是3个列表,包含整数文件描述符,或者带有可返回文件描述符的fileno()方法对象。第一个参数是需要等待输入的对象,第二个指定等待输出的对象,第三个参数指定异常情况的对象。第四个参数则为设置超时时间,是一个浮点数。指定以秒为单位的超时值。select函数将会返回一组文件描述符,包括输入,输出以及异常。

在linux下利用select实现多路IO的文件复制程序:

#!/usr/bin/env python
import select
#导入select模块
BLKSIZE=8192
def readwrite(fromfd,tofd):
readbuf = fromfd.read(BLKSIZE)
if readbuf:
tofd.write(readbuf)
tofd.flush()
return len(readbuf)
def copy2file(fromfd1,tofd1,fromfd2,tofd2):
”’ using select to choice fds”’
totalbytes=0
if not (fromfd1 or fromfd2 or tofd1 or tofd2) :
#检查所有文件描述符是否合法
return 0
while True:
#开始利用select对输入所有输入的文件描述符进行监视
rs,ws,es = select.select([fromfd1,fromfd2],[],[])
for r in rs:
if r is fromfd1:
#当第一个文件描述符可读时,读入数据
bytesread = readwrite(fromfd1,tofd1)
totalbytes += bytesread
if r is fromfd2:
bytesread = readwrite(fromfd2,tofd2)
totalbytes += bytesread
if (bytesread <= 0): break return totalbytes def main(): fromfd1 = open("/etc/fstab","r") fromfd2 = open("/etc/passwd","r") tofd1 = open("/root/fstab","w+") tofd2 = open("/root/passwd","w+") totalbytes = copy2file(fromfd1,tofd1,fromfd2,tofd2) print "Number of bytes copied %dn" % totalbytes return 0 if __name__=="__main__": main() [/code]
通过select模块实现异步IO的方法就是这样,欢迎大家参考。。。。

python通过poll实现异步I/O的方法

python如何通过poll实现异步I/O的方法?下面会通过详细的实例来介绍python中poll的用法:

本文实例讲述了Python通过poll实现异步IO的方法。分享给大家供大家参考。具体分析如下:

在使用poll()后返回轮询对象,该对象支持以下方法:
pollObj.register(fd,[,eventmask])第一个参数是注册新的文件描述符fd,fd要么是一个整数文件描述符,要么可以带有一个获取文件描述符的fileno()方法的对象。eventmask是一些按位或标记,这些标记指示要处理的事件。

POLLIN: 用于读取数据
POLLPRI: 用于读取紧急数据
POLLOUT: 准备写入
POLLERR: 错误情况
POLLHUP: 保持状态
POLLNVAL: 无效请求

最后在循环中利用pollObj.poll()来进行对已注册的文件描述符进行轮询。返回一元祖(fd,event)。其中fd是文件描述符,event是指示时间的位掩码。至需要将event与对应的时间进行&测试即可。

利用poll创建对一个多路文件复制程序,代码如下:

#!/usr/bin/env python
import select
BLKSIZE=8192
def readwrite(fromfd,tofd):
readbuf = fromfd.read(BLKSIZE)
if readbuf:
tofd.write(readbuf)
tofd.flush()
return len(readbuf)
def copyPoll(fromfd1,tofd1,fromfd2,tofd2):
#定义需要监听的事件
READ_ONLY = (select.POLLIN |
select.POLLPRI |
select.POLLHUP |
select.POLLERR )
totalbytes=0
if not (fromfd1 or fromfd2 or tofd1 or tofd2) :
return 0
fd_dict = {fromfd1.fileno():fromfd1,fromfd2.fileno():fromfd2}
#创建poll对象p
p=select.poll()
#利用poll对象p对需要监视的文件描述符进行注册
p.register(fromfd1,READ_ONLY)
p.register(fromfd2,READ_ONLY)
while True:
#轮询已经注册的文件描述符是否已经准备好
result = p.poll()
if len(result) != 0:
for fd,events in result:
if fd_dict[fd] is fromfd1:
if events & (select.POLLIN|select.POLLPRI):
bytesread = readwrite(fromfd1,tofd1)
totalbytes+=bytesread
elif events & (select.POLLERR):
p.unregister(fd_dict[fd])
if fd_dict[fd] is fromfd2:
if events & (select.POLLIN|select.POLLPRI):
bytesread = readwrite(fromfd2,tofd2)
totalbytes+=bytesread
elif events & (select.POLLERR):
p.unregister(fd_dict[fd])
if bytesread <= 0: break return totalbytes def main(): fromfd1 = open("/etc/fstab","r") fromfd2 = open("/root/VMwareTools-8.8.1-528969.tar.gz","r") tofd1 = open("/root/fstab","w+") tofd2 = open("/var/passwd","w+") totalbytes = copyPoll(fromfd1,tofd1,fromfd2,tofd2) print "Number of bytes copied %dn" % totalbytes return 0 if __name__=="__main__": main() [/code]
python通过poll实现异步I/O的方法就是这样,欢迎大家参考。。。。

python中文件及目录的操作方法

python中如何来操作文件以及目录?下面会通过详细的实例来介绍python中对文件以及目录的使用:

本文实例讲述了Python文件及目录操作的方法。分享给大家供大家参考。具体分析如下:

在python中对文件及目录的操作一般涉及多os模块,os.path模块。具体函数以及使用方法在程序中说明。

#!/usr/bin/env python
#-*- coding=UTF8 -*-
import os
import os.path as op
def change_dir():
  '''
 该函数显示及改变前目录
 using chdir() to change current dir
    getcwd() can show the current working directory
  '''
  directory="/tmp"
  #使用getcwd()返回当前目录
  print os.getcwd()
  #chdir改变当前目录为:directory目录
  os.chdir(directory)
  print os.getcwd()
def show_filesOfdir(whichDir):
  '''
 此函数只显示目录下的所有文件
 using listdir() to shows all of the file execpt directory
   join() function catenate 'whichDir' with listdir() returns values
   isfile() check that file is a regular file
   '''
   #listdir() 函数显示前目录的内容
  for file in os.listdir(whichDir):
 #利用join()把whichDir目录及listdir() 返回值连接起来组成合法路径
    file_name = op.join(whichDir,file)
 #isfile()函数可以判断该路径上的文件是否为一个普通文件
    if op.isfile(file_name):
      print file_name
def printaccess(path):
  '''
 显示文件的最后访问时间,修改时间
 shows 'path' the last access time
      getatime() return the time of last access of path
   stat() return information of a file,use its st_atime return the time of last access
   ctime() return a string of local time
  '''
  import time
  #利用ctime()函数返回最后访问时间
  #getatime()函数返回最后访问时间,不过是以秒为单位(从新纪元起计算)
  print time.ctime(op.getatime(path))
  #stat()函数返回一个对象包含文件的信息
  stat = os.stat(path)
  #st_atime 最后一次访问的时间
  print time.ctime(stat.st_atime)
  print the modify time
  print "modify time is:",
  print time.ctime(op.getctime(path))
  print "modify time is:",
  #st_ctime 最后一次修改的时间
  print time.ctime(stat.st_ctime)
def isDIR(path):
  '''
 一个os.path.isdir()函数的实现
 Implement isdir() function by myself
  '''
  import stat
  MODE = os.stat(path).st_mode
  #返回真假值
  return stat.S_ISDIR(MODE)
if __name__== "__main__":
  change_dir()
  show_filesOfdir('''/root''')
  printaccess('/etc/passwd')
  print isDIR('/etc')
 


python中文件及目录的操作方法就是这样,欢迎大家参考。。。。

python中fork进程的用法

在python中如何使用fork来创建新的进程?下面会通过详细的实例来介绍python中fork的用法:

本文实例讲述了python创建进程fork用法。分享给大家供大家参考。具体分析如下:

#!coding=utf-8
import os ,traceback
import time
'''
fork()系统调用是Unix下以自身进程创建子进程的系统调用,
一次调用,两次返回,如果返回是0,
则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid)
'''
source = 10
i = 0
try:
  print '***********************'
  pid = os.fork()
  #这里会返回两次,所以下面的省略号会输出2次
  print '......'
  if pid == 0:#子进程
    print "this is child process"
    source = source - 1
    print 'child process source is ',source
    time.sleep(10)
    print 'child sleep done'
  else:  #父进程
    print "this is parent process"
    print 'parent process source is ',source
    time.sleep(10)
    print 'parent sleep done'
  print source
except:
  traceback.print_exc()
 

输出如下:

***********************
......
this is child process
child process source is 9
......
this is parent process
parent process source is 10
child sleep done
9
parent sleep done
10
 


python中fork进程的用法就是这样,欢迎大家参考。。。。

python中Django框架如何通过ajax发起请求并返回JSON格式数据的方法

在python的开源框架Django中,如何通过前端的ajax技术发出请求并返回JSON格式的数据呢?下面会通过详细的实例来演示实现的方法:

本文实例讲述了django通过ajax发起请求返回JSON格式数据的方法。分享给大家供大家参考。具体实现方法如下:

这是后台处理的:

def checkemail(request):
  user = None
  if request.POST.has_key('email'):
    useremail = request.POST['email']
    result = {}
    user = User.objects.filter(useremail__iexact = useremail)
  if user:
    result = "1"
    result = simplejson.dumps(result)
  else:
    result = "0"
    result = simplejson.dumps(result)
  return HttpResponse(result, mimetype='application/javascript')
 

这是AJAX部分:

if(valid_email($('#reg-for-email').val())){
  var email = $('#reg-for-email').val();
  //这里把用户输入的EMAIL地址提交到后台数据库中去验证是否已存在。
  $.ajax({
    type:"POST" ,
    url:"/reg/checkemail",
    data:"email=" + email ,
    cache: false,
    success: function(result){
  if (result==1)
   {
    $("#reg-for-email-msg").removeClass("g-hide");
    $('#reg-for-email-msg').removeClass("msg-isok").addClass("msg-error").html("该邮箱已存在!");
    eok = true;
   }
   else
   {
    $("#reg-for-email-msg").addClass("g-hide");
    eok = false;
   }
    }
   })
}
 

URL的配置是:

url(r'^reg/checkemail/', 'reg.views.checkemail', name='ce'), 


python中Django框架如何通过ajax发起请求并返回JSON格式数据的方法就是这样,欢迎大家参考。。。。

python中threading模块里join函数的用法

在python中threading模块里的join函数是如何使用的?下面会通过详细的实例来演示join函数的使用和相关技巧

本文实例讲述了Python中threading模块join函数用法。分享给大家供大家参考。具体分析如下:

join的作用是众所周知的,阻塞进程直到线程执行完毕。通用的做法是我们启动一批线程,最后join这些线程结束,例如:

for i in range(10):
 t = ThreadTest(i)
 thread_arr.append(t)
for i in range(10):
 thread_arr[i].start()
for i in range(10):
 thread_arr[i].join()
 

此处join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。

而py的join函数还有一个特殊的功能就是可以设置超时,如下:

Thread.join([timeout])

Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs.
也就是通过传给join一个参数来设置超时,也就是超过指定时间join就不在阻塞进程。而在实际应用测试的时候发现并不是所有的线程在超时时间内都结束的,而是顺序执行检验是否在time_out时间内超时,例如,超时时间设置成2s,前面一个线程在没有完成的情况下,后面线程执行join会从上一个线程结束时间起再设置2s的超时。


python中threading模块里join函数的用法就是这样,欢迎大家参考。。。。

python中获取一个月多少天的方法介绍

在python中如何来实现获取每个月天数的方法,下面会通过使用python中的calendar模块来实现这个需求:

本文实例讲述了python获得一个月有多少天的方法。分享给大家供大家参考。具体分析如下:

在python的datetime模块中没有一个月有多少天的方法,但是可以使用calendar模块获得。

如下代码:

import calendar
monthRange = calendar.monthrange(2013,6)
print monthRange
 

输出:

(5,30)

输出的是一个元组,第一个元素是月份(0-11),第二个元素是这个月的天数。


python中获取一个月多少天的方法介绍就是这样,欢迎大家参考。。。。

python中类装饰器用法

在python中类装饰器是如何使用的,下面将会通过实例来介绍类装饰器用法以及技巧:

本文实例讲述了python类装饰器用法。分享给大家供大家参考。具体如下:

#!coding=utf-8
registry = {}
def register(cls):
  registry[cls.__clsid__] = cls
  return cls
@register
class Foo(object):
  __clsid__ = '123-456'
  def bar(self):
    pass
print registry
 

运行结果如下:

{‘123-456’: }


类装饰器就是这样,欢迎大家参考。。。。

python中函数的参数定义和可变参数的用法

在python中函数的参数定义和可变参数是如何使用的,下面将会通过实例来介绍函数的参数定义和可变参数用法以及技巧:

本文实例讲述了Python中函数的参数定义和可变参数用法。分享给大家供大家参考。具体如下:

刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解。其实只要把函数参数定义搞清楚了,就不难理解了。

先说说函数定义,我们都知道,下面的代码定义了一个函数funcA

def funcA():
 pass
 

显然,函数funcA没有参数(同时啥也不干:D)。

下面这个函数funcB就有两个参数了,

def funcB(a, b):
 print a
 print b
 

调用的时候,我们需要使用函数名,加上圆括号扩起来的参数列表,比如 funcB(100, 99),执行结果是:

100
99

很明显,参数的顺序和个数要和函数定义中一致,如果执行funcB(100),Python会报错的:

TypeError: funcB() takes exactly 2 arguments (1 given)

我们可以在函数定义中使用参数默认值,比如

def funcC(a, b=0):
 print a
 print b
 

在函数funcC的定义中,参数b有默认值,是一个可选参数,如果我们调用funcC(100),b会自动赋值为0。

OK,目前为止,我们要定义一个函数的时候,必须要预先定义这个函数需要多少个参数(或者说可以接受多少个参数)。一般情况下这是没问题的,但是也有在定义函数的时候,不能知道参数个数的情况(想一想C语言里的printf函数),在Python里,带*的参数就是用来接受可变数量参数的。看一个例子

def funcD(a, b, *c):
 print a
 print b
 print "length of c is: %d " % len(c)
 print c
 

调用funcD(1, 2, 3, 4, 5, 6)结果是

1
2
length of c is: 4
(3, 4, 5, 6)

我们看到,前面两个参数被a、b接受了,剩下的4个参数,全部被c接受了,c在这里是一个tuple。我们在调用funcD的时候,至少要传递2个参数,2个以上的参数,都放到c里了,如果只有两个参数,那么c就是一个empty tuple。

好了,一颗星我们弄清楚了,下面轮到两颗星。

上面的例子里,调用函数的时候,传递的参数都是根据位置来跟函数定义里的参数表匹配的,比如funcB(100, 99)和funcB(99, 100)的执行结果是不一样的。在Python里,还支持一种用关键字参数(keyword argument)调用函数的办法,也就是在调用函数的时候,明确指定参数值付给那个形参。比如还是上面的funcB(a, b),我们通过这两种方式调用
funcB(a=100, b=99)

funcB(b=99, a=100)

结果跟funcB(100, 99)都是一样的,因为我们在使用关键字参数调用的时候,指定了把100赋值给a,99赋值给b。也就是说,关键字参数可以让我们在调用函数的时候打乱参数传递的顺序!

另外,在函数调用中,可以混合使用基于位置匹配的参数和关键字参数,前题是先给出固定位置的参数,比如

def funcE(a, b, c):
 print a
 print b
 print c
 

调用funcE(100, 99, 98)和调用funcE(100, c=98, b=99)的结果是一样的。

好了,经过以上铺垫,两颗星总算可以出场了:
如果一个函数定义中的最后一个形参有 ** (双星号)前缀,所有正常形参之外的其他的关键字参数都将被放置在一个字典中传递给函数,比如:

def funcF(a, **b):
 print a
 for x in b:
  print x + ": " + str(b[x])
 

调用funcF(100, c=’你好’, b=200),执行结果

100
c: 你好
b: 200

大家可以看到,b是一个dict对象实例,它接受了关键字参数b和c。

常规参数,*参数及**参数可以同时使用,具体怎么用?看看Python Reference Manual吧,关于Function definitions的那些章节。其实,笨想也能猜出来啊,o(∩_∩)o…


python中函数的参数定义和可变参数的用法就是这样,欢迎大家参考。。。。

python中函数装饰器的用法

在python中函数装饰器是如何使用的,下面将会通过实例来介绍python中函数装饰器的使用方法以及技巧:

本文实例讲述了python函数装饰器用法。分享给大家供大家参考。具体如下:

装饰器经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

#! coding=utf-8
import time
def timeit(func):
  def wrapper(a):
    start = time.clock()
    func(1,2)
    end =time.clock()
    print 'used:', end - start
    print a
  return wrapper
@timeit
# foo = timeit(foo)完全等价,
# 使用之后,foo函数就变了,相当于是wrapper了
def foo(a,b):
  pass
#不带参数的装饰器
# wraper 将fn进行装饰,return wraper ,返回的wraper 就是装饰之后的fn
def test(func):
  def wraper():
    print "test start"
    func()
    print "end start"
  return wraper
@test
def foo():
  print "in foo"
foo()
 

输出:

test start
in foo
end start
 

装饰器修饰带参数的函数:

def parameter_test(func):
  def wraper(a):
    print "test start"
    func(a)
    print "end start"
  return wraper
@parameter_test
def parameter_foo(a):
  print "parameter_foo:"+a
#parameter_foo('hello')
 

输出:

>>>
test start
parameter_foo:hello
end start
 

装饰器修饰不确定参数个数的函数:

def much_test(func):
  def wraper(*args, **kwargs):
    print "test start"
    func(*args, **kwargs)
    print "end start"
  return wraper
@much_test
def much1(a):
  print a
@much_test
def much2(a,b,c,d ):
  print a,b,c,d
much1('a')
much2(1,2,3,4)
 

输出:

test start
a
end start
test start
1 2 3 4
end start
 

带参数的装饰器,再包一层就可以了:

def tp(name,age):
  def much_test(func):
    print 'in much_test'
    def wraper(*args, **kwargs):
      print "test start"
      print str(name),'at:'+str(age)
      func(*args, **kwargs)
      print "end start"
    return wraper
  return much_test
@tp('one','10')
def tpTest(parameter):
  print parameter
tpTest('python....')
 

输出:

in much_test
test start
one at:10
python....
end start
 
class locker:
  def __init__(self):
    print("locker.__init__() should be not called.")
  @staticmethod
  def acquire():
    print("locker.acquire() called.(这是静态方法)")
  @staticmethod
  def release():
    print("locker.release() called.(不需要对象实例")
def deco(cls):
  '''cls 必须实现acquire和release静态方法'''
  def _deco(func):
    def __deco():
      print("before %s called [%s]." % (func.__name__, cls))
      cls.acquire()
      try:
        return func()
      finally:
        cls.release()
    return __deco
  return _deco
@deco(locker)
def myfunc():
  print(" myfunc() called.")
myfunc()
 

输出:

>>>
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
 myfunc() called.
locker.release() called.(不需要对象实例
>>>
 
class mylocker:
  def __init__(self):
    print("mylocker.__init__() called.")
  @staticmethod
  def acquire():
    print("mylocker.acquire() called.")
  @staticmethod
  def unlock():
    print(" mylocker.unlock() called.")
class lockerex(mylocker):
  @staticmethod
  def acquire():
    print("lockerex.acquire() called.")
  @staticmethod
  def unlock():
    print(" lockerex.unlock() called.")
def lockhelper(cls):
  '''cls 必须实现acquire和release静态方法'''
  def _deco(func):
    def __deco(*args, **kwargs):
      print("before %s called." % func.__name__)
      cls.acquire()
      try:
        return func(*args, **kwargs)
      finally:
        cls.unlock()
    return __deco
  return _deco
class example:
  @lockhelper(mylocker)
  def myfunc(self):
    print(" myfunc() called.")
  @lockhelper(mylocker)
  @lockhelper(lockerex)
  def myfunc2(self, a, b):
    print(" myfunc2() called.")
    return a + b
if __name__=="__main__":
  a = example()
  a.myfunc()
  print(a.myfunc())
  print(a.myfunc2(1, 2))
  print(a.myfunc2(3, 4))
 

输出:

before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
None
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
3
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
7
 


python中函数装饰器的用法就是这样,欢迎大家参考。。。。

python生成器generator的用法

在python中如何使用generator生成器,下面将会介绍python生成器的使用方法以及技巧:

本文实例讲述了python生成器generator用法。分享给大家供大家参考。具体如下:

使用yield,可以让函数生成一个结果序列,而不仅仅是一个值

例如:

def countdown(n):
  print "counting down"
  while n>0:
    yield n #生成一个n值
    n -=1
>>> c = countdown(5)
>>> c.next()
counting down
5
>>> c.next()
4
>>> c.next()
3
 

next()调用生成器函数一直运行到下一条yield语句为止,此时next()将返回值传递给yield.而且函数将暂停中止执行。再次调用时next()时,函数将继续执行yield之后的语句。此过程持续执行到函数返回为止。

通常不会像上面那样手动调用next(), 而是使用for循环,例如:

>>> for i in countdown(5):
...   print i
...
counting down
5
4
3
2
1
 

next(), send()的返回值都是yield 后面的参数, send()跟next()的区别是send()是发送一个参数给(yield n)的表达式,作为其返回值给m, 而next()是发送一个None给(yield n)表达式, 这里需要区分的是,一个是调用next(),send()时候的返回值,一个是(yield n)的返回值,两者是不一样的.看输出结果可以区分。

def h(n):
  while n>0:
    m = (yield n)
    print "m is "+str(m)
    n-=1
    print "n is "+str(n)
>>> p= h(5)
>>> p.next()
5
>>> p.next()
m is None
n is 4
4
>>> p.send("test")
m is test
n is 3
3
 


python生成器generator的用法就是这样,欢迎大家参考。。。。

python中字符串前面加r的作用

在python字符串的使用者,如果在字符串前面加r字符,可以实现字符串的特殊字符不会发生转义,下面通过实例来演示r的用法:

本文实例讲述了python中字符串前面加r的作用。分享给大家供大家参考。具体分析如下:

字符串前面加r,表示的意思是禁止字符串转义

>>> print "asfdasn"
asfdas
>>> print "asfdas\n"
asfdasn
>>> print "asfdasn"
asfdas
>>> print r"asfdasn"
asfdasn
 


python中字符串前面加r的作用就是这样,欢迎大家参考。。。。

python中避免死锁的方法介绍

在python中经常会导致死锁发生,那么如何才能很好的避免死锁的发生呢?下面将会介绍几个python中避免死锁的方法:

本文实例讲述了python避免死锁方法。分享给大家供大家参考。具体分析如下:

当两个或者更多的线程在等待资源的时候就会产生死锁,两个线程相互等待。
在本文实例中 thread1 等待thread2释放block , thread2等待thtead1释放ablock,
避免死锁的原则:

1. 一定要以一个固定的顺序来取得锁,这个列子中,意味着首先要取得alock, 然后再去block

2. 一定要按照与取得锁相反的顺序释放锁,这里,应该先释放block,然后是alock

import threading ,time
a = 5
alock = threading.Lock()
b = 5
block = threading.Lock()
def thread1calc():
  print "thread1 acquiring lock a"
  alock.acquire()
  time.sleep(5)
  print "thread1 acquiring lock b"
  block.acquire()
  a+=5
  b+=5
  print "thread1 releasing both locks"
  block.release()
  alock.release()
def thread2calc():
  print "thread2 acquiring lock b"
  block.acquire()
  time.sleep(5)
  print "thread2 acquiring lock a"
  alock.acquire()
  time.sleep(5)
  a+=10
  b+=10
  print "thread2 releasing both locks"
  block.release()
  alock.release()
t = threading.Thread(target = thread1calc)
t.setDaemon(1)
t.start()
t = threading.Thread(target = thread2calc)
t.setDaemon(2)
t.start()
while 1:
  time.sleep(300)
 

输出:

thread1 acquiring lock a
thread2 acquiring lock b
thread1 acquiring lock b
thread2 acquiring lock a
 


python中避免死锁的方法介绍就是这样,欢迎大家参考。。。。

python中定时器timer的用法解析

在python中如何通过使用timer类来实现程序的延迟,下面的内容将会通过一个例子来介绍Timer类,并实现定时器延迟调用::

本文实例讲述了python定时器(Timer)用法。分享给大家供大家参考。具体如下:

# encoding: UTF-8
import threading
#Timer(定时器)是Thread的派生类,
#用于在指定时间后调用一个方法。
def func():
  print 'hello timer!'
timer = threading.Timer(5, func)
timer.start()
 

该程序可实现延迟5秒后调用func方法的功能。


python中定时器timer的用法就是这样,欢迎大家参考。。。。

python中管道的用法解析

在python中如何来创建,输入,输出,关闭管道呢,下面的文章将会通过实际的例子来演示这几个操作:

本文实例讲述了python中管道用法。分享给大家供大家参考。具体如下:

#!coding=utf-8
import multiprocessing
def consumer(pipe):
  output_p , input_p = pipe
  input_p.close() #关闭管道的输入端
  while True:
    try:
      item = output_p.recv()
    except EOFError:
      break
    print item
  print ("consumer done")
#生产项目并将其放到队列上
def producer(sequence, input_p):
  for item in sequence:
    input_p.send(item)
if __name__ == "__main__":
  #创建管道
  (output_p , input_p ) = multiprocessing.Pipe()
  #启动使用者进程
  cons_p = multiprocessing.Process(target=consumer, args=((output_p , input_p ),))
  cons_p.start()
  #关闭生产者中的输出管道
  output_p.close()
  #生产项目
  sequence = [1,2,3,4]
  producer(sequence, input_p)
  #关闭输入管道,表示完成
  input_p.close()
  #等待使用者进行关闭
  cons_p.join()
 


python中管道的用法就是这样,欢迎大家参考。。。。

python中基于multiprocessing多进程创建方法解析

在python中我们如何来通过multiprocessing 来创建多个进程,在下面的文章里将会对python中的multiprocessing 模块做一个介绍,并通过实例来演示如何基于multiprocessing 模块来创建出不同的进程:

本文实例讲述了python基于multiprocessing的多进程创建方法。分享给大家供大家参考。具体如下:

import multiprocessing
import time
def clock(interval):
  while True:
    print ("the time is %s"% time.time())
    time.sleep(interval)
if __name__=="__main__":
  p = multiprocessing.Process(target=clock,args=(15,))
  p.start() #启动进程
 

定义进程的另一种方法,继承Process类,并实现run方法:

import multiprocessing
import time
class ClockProcessing(multiprocessing.Process):
  def __init__(self, intverval):
    multiprocessing.Process.__init__(self)
    self.intverval = intverval
  def run(self):
    while True:
      print ("the time is %s"% time.time())
      time.sleep(self.interval)
if __name__=="__main__":
  p = ClockProcessing(15)
  p.start() #启动进程
 


python中基于multiprocessing多进程创建方法解析就是这样,欢迎大家参考。。。。

python中抽象基类的用法解析

在python中我们如何来定义一个抽象基类呢,抽象基类在使用的时候有哪些需要注意的规则,在下面的文章里会对python中的抽象对象做一个详细的介绍:

本文实例讲述了python抽象基类用法。分享给大家供大家参考。具体如下:

定义抽象类,需要使用abc模块,该模块定义了一个元类(ABCMeata),和装饰器 @abstractmethod, @abstractproperty
如果要实例化继承了Foo 的子类,子类必须实现了Foo所有的抽象方法(跟java一样),否则实例化报错。
抽象类不能直接实例化

#!coding=utf-8
from abc import ABCMeta, abstractmethod, abstractproperty
class Foo:
  __metaclass__ = ABCMeta
  @abstractmethod
  #在python3.0中 使用 class Foo(metaclass=ABCMeta)语法
  def spam(self, a, b):
    pass
  @abstractproperty
  def name(self):
    pass
class Bar(Foo):
  def spam(self, a, b):
    print a, b
  def name():
    pass
b = Bar()
b.spam(1,2)
 

抽象基类支持对已经存在的类进行注册,使其属于该基类,使用register()方法
向抽象基类注册某个类,对于注册类中的实例,涉及后续基类的类检测操作比如(isinstance, issubclass) 将返回True,向抽象基类注册某个类时,不会检查该类是否实现了任何抽象方法或特性,这种注册过程只会影响类型检查

class Crok(object):
  def spam(self, a, c):
    print "gork.span"
Foo.register(Grok)
 


python中抽象基类的用法解析就是这样,欢迎大家参考。。。。

python中内置函数__call__用法实例解析

在python中我们如何来使用内置函数__call__呢,在下面的内容里会对python中的内置函数__call__做详细的介绍,并通过一个实例来演示__call__的用法:

本文实例讲述了python中__call__内置函数的用法。分享给大家供大家参考。具体分析如下:

对象通过提供__call__(slef, [,*args [,**kwargs]])方法可以模拟函数的行为,如果一个对象x提供了该方法,就可以像函数一样使用它,也就是说x(arg1, arg2…) 等同于调用x.__call__(self, arg1, arg2)。模拟函数的对象可以用于创建仿函数(functor) 或代理(proxy)

class DistanceForm(object):
  def __init__(self, origin):
    self.origin = origin
    print "origin :"+str(origin)
  def __call__(self, x):
    print "x :"+str(x)
p = DistanceForm(100)
p(2000)
 

输出:

>>>
origin :100
x :2000
 


python中内置函数__call__用法实例解析就是这样,欢迎大家参考。。。。

python中协程用法实例分析

在python中,什么是协程?如何来使用协程?在下面的文章里会对协程的概念,用法做详细的介绍,通过一个实例来演示协程的用法:

本文实例讲述了python协程用法。分享给大家供大家参考。具体如下:

把函数编写为一个任务,从而能处理发送给他的一系列输入,这种函数称为协程

def print_matchs(matchtext):
  print "looking for",matchtext
  while True:
    line = (yield)
    #用 yield语句并以表达式(yield)的形式创建协程
    if matchtext in line:
      print line
>>> matcher = print_matchs('python')
>>> matcher.next()
looking for python
>>> matcher.send('hello python')#看生成器那片,关于send()跟next()的区别
hello python
>>> matcher.send('test')
>>> matcher.send('python is cool')
python is cool
>>>matcher.close()
 

希望本文所述对大家的Python程序设计有所帮助。


python中协程用法实例分析就是这样,欢迎大家参考。。。。

python中__slots__函数的用法介绍

本文主要介绍了python中__slots__函数的用法,并通过实际的例子来演示如何使用__slots__:

本文实例讲述了python中__slots__的用法。分享给大家供大家参考。具体分析如下:

定义__slots__ 后,可以再实例上分配的属性名称将被限制为指定的名称。否则将引发AttributeError,这种限制可以阻止其他人向现有的实例添加新的属性.
使用__slots__的类的实例不在使用字典来存储数据。相反,会使用基于数组的更加紧凑的数据结构。

在会创建大量对象的程序中,使用__slots__可以显著减少内存占用和使用时间

class Account(object):
  __slots__ = ('name' ,'balance')
class Test(object):
  def __init__(self ,name):
    self.name = name
 

希望本文所述对大家的Python程序设计有所帮助。


python中__slots__函数的用法介绍就是这样,欢迎大家参考。。。。

python中进程之间互相通信的用法介绍

本文主要介绍了python语言中不同进程之间通信的方法,并通过实际的例子来演示两个进程的互相通信:

本文实例讲述了Python进程间通信用法。分享给大家供大家参考。具体如下:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
import multiprocessing
def counsumer(input_q):
  while True:
    item = input_q.get()
    #处理项目
    print item #此处替换为有用的工作
    #发出信号通知任务完成
    input_q.task_done()
def producer(sequence,output_q):
  for item in sequence:
    #将项目放入队列
    output_q.put(item)
#建立进程
if __name__ == '__main__':
  q = multiprocessing.JoinableQueue()#创建可连接的共享进程队列
  cons_q = multiprocessing.Process(target=counsumer,args=(q,))
  cons_q.daemon = True
  cons_q.start()
  sequence = [1,2,3,4]
  producer(sequence,q)
  q.join()
  print 'success'
 

希望本文所述对大家的Python程序设计有所帮助。


python中进程之间互相通信的用法介绍就是这样,欢迎大家参考。。。。

python中比较两个列表范围的方法

本文主要介绍了python如何来比较两个不同的列表的范围,通过实际的例子来演示如何来实现比较列表范围的方法,并给出了详细的分析:

有一道题: 比较两个列表范围,如果包含的话,返回TRUE,否则FALSE。 详细题目如下:

Create a function, this function receives two lists as parameters, each list indicates a scope of numbers, the function judges whether list2 is included in list1.

Function signature:
differ_scope(list1, list2)

Parameters:
list1, list2 – list1 and list2 are constructed with strings,
each string indicates a number or a scope of
numbers. The number or scope are randomly, can
be overlapped. All numbers are positive.

E.g.
[’23’, ’44-67′, ’12’, ‘3’, ’20-90′] Return Values:
True – if all scopes and numbers indicated by list2 are included in list1.
False – if any scope or number in list2 is out of the range in list1.
Examples:
case1 – list1 = [’23’, ’44-67′, ’12’, ‘3’, ’20-90′] list2 = [’22-34′, ’33’, 45′, ’60-61′] differ_scope(list1, list2) == True
case2 – list1 = [’23’, ’44-67′, ’12’, ‘3’, ’20-90′] list2 = [’22-34′, ’33’, 45′, ’60-61′, ‘100’] differ_scope(list1, list2) == False

贴上自己写的代码如下:(备注: python 2.7.6)

def differ_scope(list1, list2):
  print "list1:" + str(list1)
  print "list2:" + str(list2)
  #设置临时存放列表
  list1_not_ = [] #用于存放列表1正常的数字值,当然要用int()来转换
  list1_yes_ = [] #用于存放列表1中范围值如 44-67
  list1_final = [] #用于存放列表1中最终范围值 如:[1,2,3,4,5,6,7,8,9,10]
  temp1    = []
  list2_not_ = []  #用于存放列表2正常的数字值,当然要用int()来转换
  list2_yes_ = []  #用于存放列表2中范围值如 44-67
  list2_final= []  #用于存放列表2中最终范围值 如:[1,2,3,4,5,6,7,8,9,10]
  temp2   = []
  temp    = []  #用于存放列表1,与列表2比较后的列表,从而判断结果为True还是False.
  #对列表1进行处理
  for i in range(len(list1)): #用FOR循环对列表1进行遍历
    tag = 0
    if list1[i].find('-')>0:#对含范围的数字进行处理,放到list_yes_列表中
      strlist = list1[i].split('-')
    list1_yes_ = range(int(strlist[0]),int(strlist[1])+1)#让其生成一个范围列表
    for each in list1_yes_:     #FOR循环遍历所有符合条件的.
        [temp1.append(each)]
    else:           #对列表1中正常的数字进行处理,放到list_not_列表中
      list1_not_.append(int(list1[i]))#对列表1中进行处理,放到list_yes_
  [temp1.append(i) for i in list1_not_ if not i in temp1]#去除重复项
  list1_final = sorted(temp1) #比较后,排序,并放到list1_final列表中
  print "list1_final value is:" + str(list1_final)#打印排序后最终list1_final列表
  #对列表2进行处理
  for i in range(len(list2)):
    if list2[i].find('-')>0:
      strlist = list2[i].split('-')
    list2_yes_ = range(int(strlist[0]),int(strlist[1])+1)
    for each in list2_yes_:
        [temp2.append(each)]
      print "Temp2:" + str(temp2)
    else:
      list2_not_.append(int(list2[i]))
  [temp2.append(i) for i in list2_not_ if not i in temp2]
  list2_final = sorted(temp2)
  print "list2_final value is:" + str(list2_final)
  #对两个列表进行比较,得出最终比较结果.
  [temp.append(i) for i in list2_final if not i in list1_final]#比较两个列表差值.
  print "In list2 but not in list1:%s" % (temp)#打印出列表1与列表2的差值
  if len(temp)>=1 :
    print "The result is: False"
  else:
    print "The result is: True"
if __name__ == '__main__':
  list1 = ['23', '44-67', '12', '3','90-100']
  list2 = ['22-34', '33', '45']
  differ_scope(list1,list2)
 

总结:
1. 这道题关键是想法,如果整成坐标的方式来比较,会很麻烦。
2. 列表转成范围后,如果消除重复项,同样是里面的关键所在。
3. 其次是对列表遍历的操作,同样挺重要。


python中比较两个列表范围的方法就是这样,欢迎大家参考。。。。

python 3.x版本的新特性以及10个最大的变化

本文主要介绍了python 3.x版本的新特性,说明了在使用python3.x版本时需要注意的地方,并介绍了python3.x中10个最大的变化,比如print()和exec函数的变化,源码默认的编码方式变为UTF-8等等:

Python 3.x 起始版本是Python 3.0,目前的最新版本是 3.3.3

Python之父Guido van Rossum谈到了Python 3.0的构思:

一直以来,除非要打破向后兼容性,否则很多缺陷和错误都无法修复。因此,Python 3000将会作为第一个放弃向后兼容性的Python版本,目的就是要让Python向着最好的语言前进。

Python的3.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0在设计的时候没有考虑向下兼容。许多针对早期Python版本设计的程序都无法在Python 3.0上正常运行。为了照顾现有程序,Python 2.6作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python 3.0的迁移,允许使用部分Python 3.0的语法与函数。基于早期Python版本而能正常运行于Python 2.6并无警告。程序可以通过一个2to3的转换工具无缝迁移到Python 3.0。Python有一些很有用的测试模块,包括doctext和unitest。确保在尝试移植到Python3之前,对应用程序进行全面测试。要确保测试范围尽可能大,而且程序在Python2.6上运行时,能通过测试并且没有出现任何警告信息。

新的Python程序建议使用Python 3.0版本的语法。除非运行环境无法安装Python 3.0或者程序本身使用了不支持Python 3.0的第三方库。目前不支持Python 3.0的第三方库有Twisted, py2exe, PIL等。大多数第三方库都正在努力地兼容Python 3.0版本。即使无法立即使用Python 3.0,也建议编写兼容Python 3.0版本的程序,然后使用Python 2.6, Python 2.7来运行。Python 2.7被确定为最后一个Python 2.x版本,它除了支持Python 2.x语法外,还支持部分Python 3.1语法.

变化大致总结如下:

01.print() and exec() 函数

python旧版本里,print和exec是作为一语句出现,可以用print “Hello,World!”, 来打印一个语句,在新版本里,print()和exec()作为一个函数出现,所以上面的写就是错误的,应该写成print (“Hello,World!”)对于Java的程序员来说,这样的改变应该是比较熟悉. System.out.print(“Hello,World!”);

Old: >>>print "The answer is", 2*2
New: >>>print("The answer is", 2*2)
Old: >>>print x,           # Trailing comma suppresses newline
New: >>>print(x, end=" ")  # Appends a space instead of a newline
Old: >>>print              # Prints a newline
New: >>>print()            # You must call the function!
Old: >>>print >>sys.stderr, "fatal error"
New: >>>print("fatal error", file=sys.stderr)
Old: >>>print (x, y)       # prints repr((x, y))
New: >>>print((x, y))      # Not the same as print(x, y)!
 

不过在Python 2.6版本里面: from __future__ import print_function

>>> from __future__ import print_function
>>> print ('Jerry','Sherry',sep='-')
Jerry-Sherry
 

下面的修改在新版本是正确的:

>>>print("There are <", 2**32, "> possibilities!", sep="")
There are <4294967296> possibilities!
>>>fid = open("log.txt", "a")
>>>print("log.txt", file=fid)
>>>print("Foo", "Bar", sep="%")
>>>Foo%Bar
 

exec() 同样是函数,在python 2.x里,下列代码是ok的.

>>> def foo():
 exec('a=4')
 print a
>>> foo()
4
 

但在python 3.x里面就不行了,会报NameError: global name ‘a’ is not defined. 因为变量a没有定义。原因在于exec()作为函数,只操作globals()和locals()函数返回的字典。但locals()函数返回的字典实际上是局部变量的一个副本。exec()函数中进行的赋值只修改了局部变量的这份副本,而非局部变量本身。下面给出了一种解决办法:

>>> def foo():
 _locals = locals()
 exec('a=4',globals(),_locals)
 a = _locals['a']
 print (a)
>>> foo()
4
 

02.整数及除法

int和long统一为int, int表示任何精度的整数,移除sys.maxint, 因为int已经是最大的整数。新版本移除了含糊的除法符号(’/’),而只返回浮点数。在以前的版本中,如果参数是int或者是long的话,就会返回相除后结果的向下取整(floor), 而如果参数是float或者是complex的话,那么就会返回相除后结果的一个恰当的近似。

Old: >>>1/2   #结果是0     晕死。。。
New: >>>1/2   #结果是0.5   总算接地气了。
 

03.input()代替raw_input()
变简洁了。

Old:  >>>question = raw_input("What is your quest&#63; ")
New:  >>>question = input("What is your quest&#63; ")
 

04.源文件编码默认为UTF-8
Python 3 在字符编码方面有很多改进,其中之一就是默认的源文件编码从ASCII变为UTF-8,也就是说以前在文件头加上的各种花样的 coding=utf-8不再需要了!

# coding: UTF-8
# vim:fileencoding=UTF-8
# -*- coding=UTF-8 -*-
# vim: set fileencoding=UTF-8
 

05.字符串格式化变化
格式化字符串的这个内置的%操作符太有限了,新版本新增加了format(),比以前更灵活了,%要逐渐被淘汰。举三个简单的例子如下:

>>>"I love {0}, {1}, and {2}".format("eggs", "bacon", "sausage")
'I love eggs, bacon, and sausage' 

>>>”I love {a}, {b}, and {c}”.format(a=”eggs”, b=”bacon”, c=”sausage”)
‘I love eggs, bacon, and sausage’

>>>”I love {0}, {1}, and {param}”.format(“eggs”, “bacon”, param=”sausage”)
‘I love eggs, bacon, and sausage’

python 3.x版本的新特性以及10个最大的变化就是这样,欢迎大家参考。。。。

搞笑的程序猿:看看你是哪种Python程序员

本文主要介绍了不同阶段的python程序对同一个问题编写代码的风格,方式的不同比较,比如一年经验的python程序员,懒惰的程序员,python专家,python黑客编写代码风格的不同,从中也可以看看你是属于python程序员里的哪一种:

不久前,在互联网上出现了一篇有趣的文章,讲的是对于同一个问题,不同层次的Python程序员编出的Python代码,显示出了不同的风格,代码都很简单,有趣。下面让我们一起来看看一个Python程序猿进阶的全过程吧。(偷笑)

编程新手

def factorial(x):
  if x == 0:
    return 1
  else:
    return x * factorial(x - 1) //不简单啊,迭代,新手哦。
print factorial(6)
 

一年编程经验(学Pascal的)

def factorial(x):
  result = 1
  i = 2
  while i <= x:
    resultresult = result * i
    ii = i + 1
  return result
print factorial(6)
 &#91;/code&#93;
<p><strong>一年编程经验(学C的)</strong></p>

def fact(x): #{
  result = i = 1;
  while (i <= x): #{
    result *= i;
    i += 1;
  #}
  return result;
#}
print(fact(6))
 &#91;/code&#93;
<p><strong>一年编程经验(读过SICP)</strong></p>

@tailcall
def fact(x, acc=1):
  if (x > 1):
    return (fact((x - 1), (acc * x)))
  else:
    return acc
print(fact(6))
 

一年编程经验(Python)

def Factorial(x):
  res = 1
  for i in xrange(2, x + 1):
    res *= i
    return res
 print Factorial(6)
 

懒惰的Python程序员

def fact(x):
  return x > 1 and x * fact(x - 1) or 1
print fact(6)
 

更懒的Python程序员

f = lambda x: x and x * f(x - 1) or 1 //匿名函数,厉害。程序猿真是懒人做的!
print f(6)
 

Python专家

fact = lambda x: reduce(int.__mul__, xrange(2, x + 1), 1)
print fact(6)               //专家厉害啊。
 

Python黑客

import sys
@tailcall
def fact(x, acc=1):
  if x: return fact(x.__sub__(1), acc.__mul__(x))
  return acc
sys.stdout.write(str(fact(6)) + 'n') //一般人压根看不懂。
 

专家级程序员

from c_math import fact
print fact(6)
 

大英帝国程序员

from c_maths import fact
print fact(6)
Web设计人员
def factorial(x):
  #-------------------------------------------------
  #--- Code snippet from The Math Vault     ---
  #--- Calculate factorial (C) Arthur Smith 1999 ---
  #-------------------------------------------------
  result = str(1)
  i = 1 #Thanks Adam
  while i <= x:
    #result = result * i #It's faster to use *=
    #result = str(result * result + i)
      #result = int(result *= i) #&#63;&#63;&#63;&#63;&#63;&#63;
    result = str(int(result) * i)
    #result = int(str(result) * i)
    i = i + 1
  return result
print factorial(6)
 &#91;/code&#93;
<p><strong>Unix 程序员</strong></p>

import os
def fact(x):
  os.system('factorial ' + str(x))
fact(6)
 

Windows 程序员

NULL = None
def CalculateAndPrintFactorialEx(dwNumber,
hOutputDevice,
lpLparam,
lpWparam,
lpsscSecurity,
*dwReserved):
if lpsscSecurity != NULL:
return NULL #Not implemented
dwResult = dwCounter = 1
while dwCounter <= dwNumber: dwResult *= dwCounter dwCounter += 1 hOutputDevice.write(str(dwResult)) hOutputDevice.write('n') return 1 import sys CalculateAndPrintFactorialEx(6, sys.stdout, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) //可能自己都晕菜了... [/code]

企业级程序员

def new(cls, *args, **kwargs):
return cls(*args, **kwargs)
class Number(object):
pass
class IntegralNumber(int, Number):
def toInt(self):
return new (int, self)
class InternalBase(object):
def __init__(self, base):
self.base = base.toInt()
def getBase(self):
return new (IntegralNumber, self.base)
class MathematicsSystem(object):
def __init__(self, ibase):
Abstract
@classmethod
def getInstance(cls, ibase):
try:
cls.__instance
except AttributeError:
cls.__instance = new (cls, ibase)
return cls.__instance
class StandardMathematicsSystem(MathematicsSystem):
def __init__(self, ibase):
if ibase.getBase() != new (IntegralNumber, 2):
raise NotImplementedError
self.base = ibase.getBase()
def calculateFactorial(self, target):
result = new (IntegralNumber, 1)
i = new (IntegralNumber, 2)
while i <= target: result = result * i i = i + new (IntegralNumber, 1) return result print StandardMathematicsSystem.getInstance(new (InternalBase, new (IntegralNumber, 2))).calculateFactorial(new (IntegralNumber, 6)) //面向对象,但就此题来说,又长又臭。 [/code]


搞笑的程序猿:看看你是哪种Python程序员,欢迎大家参考。。。。

python中unittest模块单元测试实例介绍

本文主要通过实际的例子来演示如何来使用python中的unittest模块来做单元测试,通过具体的待测试的类,测试类,测试结果三部分来说明unittest模块的用法:

待测试的类(Widget.py)

# Widget.py
# Python 2.7.6
class Widget:
  def __init__(self, size = (40,40)):
    self.size = size
  def getSize(self):
    return self.size
  def reSize(self,width,height):
    if width <0 or height < 0:
      raise ValueError, 'illegal size'
    else:
      self.size = (width,height)
      return self.size
  def dispose(self):
    pass
 &#91;/code&#93;
<p>测试类(Auto.py)
</p>

# coding=utf8
# Auto.dy
# Python 2.7.6
from Widget import Widget #导入测试类模块Widget
import unittest      #导入unittest模块
class WidgetTestCase(unittest.TestCase):
#让所有执行测试的类都继承于TestCase类,可以将TestCase看成是对特定类进行测试的方法的集合
  #在setUp()方法中进行测试前的初始化工作。
  def setUp(self):
    self.widget = Widget()
  #并在tearDown()方法中执行测试后的清除工作,setUp()和tearDown()都是TestCase类中定义的方法。
  def tearDown(self):
    self.widget = None
  #测试Widget类中getSize方法
  def testgetSize(self):
    print "Test GetSize"
    #对Widget类中getSize()方法的返回值和预期值进行比较,确保两者是相等的,
    #assertEqual()也是TestCase类中定义的方法。
    self.assertEqual(self.widget.getSize(), (40, 40))
  #测试Widget类中reSize方法
  def testreSize(self):
    print "Test Resize"
    #对Widget类中reSize()方法的返回值和预期值进行比较,确保两者是相等的。
    #assertEqual()也是TestCase类中定义的方法。
    self.assertEqual(self.widget.reSize(50,100),(50,100))
#提供名为suite()的全局方法,PyUnit在执行测试的过程调用suit()方法来确定有多少个测试用例需要被执行,
#可以将TestSuite看成是包含所有测试用例的一个容器。
def suite():
  suite = unittest.TestSuite()
  suite.addTest(WidgetTestCase("testgetSize"))#往此添加需要测试的方法testgetSize()
  suite.addTest(WidgetTestCase("testreSize")) #往此添加需要测试的方法testreSize()
  return suite
if __name__ == "__main__":
  unittest.main(defaultTest = 'suite') #在主函数中调用全局方法.
 

测试结果:

D:Python>python27 Auto.py
Test GetSize
.Test Resize
.
------------------------------
Ran 2 tests in 0.004s
OK
 

总结:
1。第一步:先写好测试类
2。第二步:导入unittest模块及测试的类,运用setup()方法做测试前的准备工作,如建立数据库连接,运用teardown()方法做测试后的清除工作,如取消数据库的链接,再对类中的方法逐一做测试。
3。第三步: 写suite()的全局方法,将要测试的方法,一一加入。
测试结果,有几个测试用例就有几个. 最后显示OK,表示通过。


python中unittest模块单元测试实例介绍就是这样,欢迎大家参考。。。。

python中2to3转换工具的使用介绍

本文主要介绍了python3中的2to3转换工具的使用方法,并通过实际的步骤来演示如何来使用2to3这个工具:

python3与python2的还是有诸多的不同,比如说在2中:

print "Hello,World!"
raw_input()
 

在3里面就成了:

print ("Hello,World!")
input()
 

所以如果用的python2开发的项目要迁移到3中,就需要进行代码的转换。Python3中自带了个转换工具,下面用个最简单的例子来说说2to3转换工具。
例子:(2to3Test.py 里面只有print这行代码)

# python 2.7.6
# 2to3Test.py
print "Hello,World!"
 

用python27显然是可以编译的:

D:Python>python27 2to3Test.py
Hello,World!
 

用python33就编译不过了,因为3里print是函数,这样写就会有语法错误。

D:Python>python33 2to3Test.py
  File "2to3Test.py", line 1
    print "Hello,World!"
                       ^
SyntaxError: invalid syntax
 

下面用python3中自带的2to3工具进行转换:

D:Python>python C:Python33ToolsScripts2to3.py -w 2to3Test.py
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: Refactored 2to3Test.py
--- 2to3Test.py (original)
+++ 2to3Test.py (refactored)
@@ -1 +1 @@
-print "Hello,World!"
+print("Hello,World!")
RefactoringTool: Files that were modified:
RefactoringTool: 2to3Test.py
 

最后用python33来进行编译,结果显示正确的。

D:Python>python33 2to3Test.py
Hello,World!
 

总结:
1. 目录. C:Python33ToolsScripts2to3.py. 其实在python2.6,2.7中都存在这个工具。
2. 如果不加-w参数,则默认只是把转换过程所对应的diff内容打印输出到当前窗口而已。
3. 加了-w,就是把改动内容,写回到原先的文件了。
4. 不想要生成bak文件,再加上-n即可。 bak最好还是有。


python中2to3转换工具的使用介绍就是这样,欢迎大家参考。。。。

如何在windows下实现python2和python3两个版本共存?

本文主要介绍了在windows系统下,如何才能实现让python2 和python3 这两个python 版本共同存在于系统开发环境下,通过详细的配置步骤来实现python不同的版本同时存在于windwos系统之下:

一直用的是python2,从python 2.3到python 2.7.6, 出于想了解python3的新特性,又安装了python3.3.3. 用了才发现蛮方便的。python的各个版本是独立共存的,不相互冲突的。下面说下如何操作:

1. 独自安装好python2.7.6 和 python3.3.3
2. 修改注册表: 打开->regedit
HKEY_CLASSES_ROOTPython.Fileshellopencommand的默认值
修改为”C:Python27python.exe” “%1” %*(C:Python27是我的Python2.7安装路径),
同时将C:Python27和C:Python27Scripts添加到环境变量中。

3.在C:Python27中新建一个python33.bat的文件,并运行这个文件

@ echo off
C:Python33python.exe %*
 

效果:
如果我想用python2.7.6的时候就输入 python27,想用python3.3.3的时候,就输入python33

D:Python>python27 2to3Test.py
Hello,World!
D:Python>python33 2to3Test.py
Hello,World!
 

还是挺方便的。


如何在windows下实现python2和python3两个版本共存的用法就是这样,欢迎大家参考。。。。