¼¼Êõ²©¿Í

12/04/2016 ×÷Õß ÔÆº£ÓÎÏ·

ÉîÈëÁ˽âkvmlib

ÕâÊÇʹÓÃÔÆº£ÓÎÏ· MemoratorµÚ¶þ´úÉ豸ͨ¹ýkvmlib½øÐÐÅäÖúͶÁÈ¡¼Ç¼Êý¾Ý4ƪϵÁÐÎÄÕµĵÚÈýƪ£º

ÔÚµÚһƪÎÄÕÂÖУ¬ÎÒÃÇÒѾ­½²ÊöÁËÈçºÎʹÓÃkvmlibÀ´ÅäÖÃÉ豸£¬²¢ÀûÓÃPython¶ÁÈ¡¼Ç¼µÄ±¨ÎÄ¡£ÔÚ±¾ÎÄÖУ¬ÎÒÃǽ«Óõͼ¶º¯ÊýÖØÐ²鿴ÎÒÃÇÔÚµÚһƪÎÄÕÂÖÐËùÉèµÄÅäÖá£ÕâЩµÍ¼¶º¯ÊýÓë±¾µØCÓïÑÔAPI¹²ÏíËûÃǵÄÃû³Æ£¬ËùÒÔÄãʹÓÃCÓïÑÔAPI´úÌæPythonµÄʱºò²»»áÓöµ½ÈκÎÎÊÌâ¡£ÎÒÃÇÒ²ÓйØÓÚΪVisual StudioÉèÖÃCANlibµÄϵÁв©ÎÄ£¬¿ÉÄÜ»á¶ÔÄãÓÐÓá£È«²¿³ÌÐòÁбí¿ÉÔÚGitHubÉÏ»ñµÃ¡£

3.1 ´ò¿ªÉ豸

ʹÓÃCANlib´ò¿ªÉ豸ÐèÒªµÄ֪ʶ²»½ö½öÊÇÖªµÀ±àÂ루EAN£©¡£ µ±Ê¹ÓÃPythons kvDeviceÄ£¿éÁ¬½Óµ½É豸ʱ£¬´úÂëÔÚÄÚ²¿²é¿´Á¬½Óµ½ÎÒÃǼÆËã»úµÄËùÓÐÉ豸£¬²¢·µ»ØÓëÎÒÃǵÄËÑË÷Ìõ¼þÆ¥ÅäµÄµÚÒ»¸öÉ豸£¬ÔÚÎÒÃǵÄÀý×ÓÖÐÊDZàÂë¡£

# Connect to our ÔÆº£ÓÎÏ· Memorator Pro 5xHS with EAN 00778-9
dev = kvDevice.kvDevice(ean="73-30130-00778-9")
print dev

Áбí11£º´òÓ¡ÓйØÒÑÁ¬½ÓµÄÔÆº£ÓÎÏ·É豸ÐÅÏ¢

>>> Device: ÔÆº£ÓÎÏ· Memorator Pro 5xHS (channel 0)
EAN : 73-30130-00778-9
S/N : 1023
FW : v3.0.546
Card : 0
Drv : kcany0a
Card channel : 0
Canlib channel: 0

ÔÚÕâÀïÎÒÃÇ×¢Òâµ½ÎÒÃǵÄÉ豸Á¬½Óµ½CANlibͨµÀ0ºÍCardͨµÀºÅ0¡£µ±´ÓCANlib´ò¿ªÉ豸ʱʹÓÃCANlibͨµÀºÅ£¬²¢ÇÒÔÚkvmlibÖдò¿ªÉ豸ʱÒÔÏàÓ¦µÄ·½Ê½Ê¹ÓÃCardͨµÀºÅ1¡£Èç¹ûÎÒÃÇÒÑ´ò¿ªµÚ¶þ̨É豸£¬ÄÇЩÊý×ÖÔÚµÚ¶þ̨É豸ÉϽ«²»Í¬¡£

µ±Ê¹ÓÃkvmlib´ò¿ªÎÒÃǵÄÉ豸ʱ£¬³ýÁËʹÓÃCardͨµÀÖ¸¶¨É豸֮Í⣬ÎÒÃÇ»¹ÐèÒªÖ¸¶¨É豸ÀàÐÍ¡£É豸ÀàÐÍÓÃÓÚ¾ö¶¨É豸ʹÓõÄLIOÊý¾Ý¸ñʽµÄ°æ±¾2¡£v3.0°æ±¾µÄ¹Ì¼þʹÓÃÉ豸ÀàÐÍ¡°kvmDEVICE_MHYDRA_EXT¡±¡£

ÈÃÎÒÃÇÀ´¿´¿´ÈçºÎÖ±½ÓʹÓÃkvmlibÉèÖÃÉ豸ʱÖÓ£¬ÕâÓëÄãÈçºÎʹÓÃCÓïÑÔAPI½øÐÐÉèÖÃÏàÒ»Ö¡£

ml = kvmlib.kvmlib()

# Since our firmware is v3.0 we should be using kvmDEVICE_MHYDRA_EXT
# as the device type.
deviceType = kvmlib.kvmDEVICE_MHYDRA_EXT

# We know that our device is connected to Card channel number 0
cardChannel = 0
 
# We have firmware version 3.0 in our device, this means that
# the FW is using Lio Data Format v5.0 and we should use
# kvmDEVICE_MHYDRA_EXT as the deviceType
ml.deviceOpen(memoNr=cardChannel, devicetype=deviceType)

# Having obtained a kvmHandle, we can now e.g. check the
# device serial number
print "Serial number:%d" % ml.deviceGetSerialNumber()
  
# Set the real time clock of the device
ml.deviceSetRTC(datetime.datetime.now())
  
# Read the device time
print "Current device time is %s" % ml.deviceGetRTC()
 
# Close device
ml.close()

Áбí12£ºÊ¹ÓÃkvmlibÉèÖÃÔÆº£ÓÎÏ·É豸µÄʵʱʱÖÓ

Serial number:1023
Current time is 2016-02-11 13:01:00.509000
Setting time...
Current device time is 2016-02-11 13:01:00

3.2 ³õʼ»¯SD¿¨

ÈçǰËùÊö£¬´ò¿ªÉ豸ʱʹÓÃÕýÈ·µÄÉ豸ÀàÐͷdz£ÖØÒª¡£Èç¹ûÎÒÃÇʹÓôíÎóµÄLIOÊý¾Ý¸ñʽ£¨²Î¿¼Ê¹ÓÃÉ豸ÀàÐÍ£©´ò¿ªÉ豸£¬ÎÒÃǽ«ÎÞ·¨ÔÚ¶ÁÈ¡ÆÚ¼ä¿´µ½ÈκÎÈÕÖ¾±¨ÎÄ¡£ÔÚ³õʼ»¯SD¿¨Ê±Ê¹ÓÃÕýÈ·µÄÉ豸ÀàÐ͸üÎªÖØÒª£¬ÒòΪ¹Ì¼þ½«ÎÞ·¨·ÃÎÊʹÓò»ÕýÈ·µÄLIOÊý¾Ý¸ñʽ³õʼ»¯µÄSD¿¨¡£

ÏëÒª³õʼ»¯SD¿¨£¬ÐèʹÓÃkvmlib´ò¿ªkvmHandle£¬´Ë´¦ÎÒÃÇÐèÒªÌṩÎÒÃǵÄÉ豸ÀàÐÍ£¬ËüÔÚÔÆº£ÓÎÏ· MemoratorµÚ¶þ´úÉ豸£¨ÔËÐÐÔÚfw v3.0£©ÉÏÊÇkvmDEVICE_MHYDRA_EXT.3

µ÷ÓÃdeviceMountKmf()·µ»ØLIOÊý¾Ý¸ñʽ£¬Òò´ËÎÒÃÇ¿ÉÒÔ·½±ãµØ¼ì²éÎÒÃÇÌṩµÄÊÇÕýÈ·µÄÉ豸ÀàÐÍ¡£ÔÚÏÂÃæµÄ´úÂëÖУ¬ÎÒÃǿɿ´µ½SD¿¨ÉÐδ³õʼ»¯µÄÇé¿ö¡£

´ó¶àÊýSD¿¨±»·ÖÅäÓÃÓÚÔÚ³õʼ»¯ÆÚ¼ä¼Ç¼ÈÕÖ¾±¨ÎÄ£¬µ«ÎÒÃÇ¿ÉÒÔͨ¹ý´«µÝÁ½¸ö²»Í¬µÄ²ÎÊýµ½³õʼ»¯ÃüÁîÓ°ÏìÁ½ÖÖÎļþµÄ´óС¡£

µÚÒ»¸ö²ÎÊýÊÇÖ¸¶¨¡°ÎªÓû§Îļþ±£ÁôµÄ¿Õ¼ä¡±£¬ÕâÒâζ×ÅSD¿¨ÈÝÁ¿¿ÉÒÔÃâ·Ñ¹©Óû§Ê¹Óá£ÎÒÃÇ¿ÉÒÔÔÚÉ豸ÖÐÔËÐÐ/t/³ÌÐòÉú³ÉÎı¾Îļþ£¬»òÕßÎÒÃÇ¿ÉÄÜÓÐÏëÒª¸´ÖƵ½SD¿¨µÄÆäËûÓû§Îļþ¡£

µÚ¶þ¸ö²ÎÊýÓ°ÏìÃûΪDATABASE.BINµÄÎļþµÄ´óС£¬¸ÃÎļþÓÉÔÆº£ÓÎÏ· MemoratorÅäÖù¤¾ßʹÓ㬿ÉÄܰüº¬Óû§¿ÉÑ¡Ôñ±£´æµ½SD¿¨µÄÅäÖúÍÊý¾Ý¿âÎļþ¡£

ml = kvmlib.kvmlib()
  
# Since our firmware is v3.0 we should be using kvmDEVICE_MHYDRA_EXT
# as the device type.
deviceType = kvmlib.kvmDEVICE_MHYDRA_EXT
 
# We saw earlier that our device is connected to Card channel number 0
cardChannel = 0
 
# Open the device
ml.deviceOpen(memoNr=cardChannel, devicetype=deviceType)
  
try:
    # Mount the log area
    lioDataFormat = ml.deviceMountKmf()
    print "Lio Data Format v%s" % lioDataFormat
    # Verify that the LIO data format of the card corresponds to
    # the device type we used when opening the device
    if lioDataFormat != '5.0':
        print "Unexpected Lio Data Format:", lioDataFormat
        if lioDataFormat == '3.0':
            print("This log file can be read if you reopen the"
                  " device as kvmDEVICE_MHYDRA.")
        exit(1)
except kvmlib.kvmDiskNotFormated:
    print "SD card is not initialized..."
    exit(1)
  
# Format the SD Card and reserve 10 MB for configuration files
# (i.e. DATABASE.BIN) and 1000 MB for our own files.
print "Initializing SD card..."
ml.deviceFormatDisk(reserveSpace=10000, dbaseSpace=10)
  
# Report info about the disk area allocated for logging
(diskSize, usedDiskSize) = ml.kmfGetUsage()
print "Log size: %d MB\nUsed: %d MB" % (diskSize, usedDiskSize)
  
# Close the device
ml.close()

Áбí13£ºÑéÖ¤LIOÊý¾Ý¸ñʽ²¢³õʼ»¯Ôƺ£ÓÎÏ·É豸´ÅÅÌ

Lio Data Format v5.0 Initializing SD card... Log size: 6112 MB Used: 0 MB

ÎÒÃǵÄÉ豸Åä16GBµÄSD¿¨£¬µ±ÎÒÃÇÏÖÔÚΪDATABASE.BINÔ¤Áô10MB¿Õ¼äÒÔ¼°10GB¿ÉÓÿռ䣬ÎÒÃÇÊ£ÏÂ6112MB¿ÉÓÃÓڼǼÊý¾Ý¡£ÓÉÓÚÎÒÃǸոճõʼ»¯ÁËSD¿¨£¬ÒѼǼÊý¾ÝΪ0MB£¨ÒÑʹÓã©¡£

É豸SD¿¨ÏÖÔÚÒѳõʼ»¯£¬¿ÉÒÔ½øÐÐÅäÖá£

3.3 ±£´æÅäÖÃ

ÒªÅäÖÃÉ豸£¬ÎÒÃǽ«ÒÑÑéÖ¤µÄXMLÅäÖÃת»»Îª¶þ½øÖÆÅäÖò¢½«´Ë¶þ½øÖÆÅäÖÃÏÂÔØµ½É豸¡£Õâ¾ÍÏñÎÒÃÇÔÚÕâ¸ö²©ÎÄϵÁеĵÚһƪÎÄÕÂÖÐ×öµÄÒ»Ñù£¬µ«ÊÇÔÚÕâÀïÎÒÃÇÖ±½Óµ÷ÓÃkvmlib£¬Òò´ËÐèÒª¹«¿ªdeviceTypeºÍcardChannelµÄÓ÷¨¡£

ml = kvmlib.kvmlib()
xl = kvaMemoLibXml.kvaMemoLibXml()
  
# Since our firmware is v3.0 we should be using kvmDEVICE_MHYDRA_EXT
# as the device type.
deviceType = kvmlib.kvmDEVICE_MHYDRA_EXT
  
# We saw earlier that our device is connected to Card channel number 0
cardChannel = 0
  
# Read in the XML configuration file
with open("config.xml", 'r') as myfile:
    config_xml = myfile.read()
  
# Convert the XML configuration to a binary configuration
config_lif = xl.kvaXmlToBuffer(config_xml)
  
# Open the device and write the configuration
ml.deviceOpen(memoNr=cardChannel, devicetype=deviceType)
ml.kmfWriteConfig(config_lif)
  
# Close the device
ml.close()

Áбí14£º½«ÅäÖÃת»»ºÍÏÂÔØµ½Ôƺ£ÓÎÏ·É豸

ΪÁËÒÔºóÄܹ»ÒÔÃ÷ÎļìË÷ÅäÖã¬ÎÒÃǶÔÒѾ­Ê¹ÓúÍÏÂÔØµ½É豸ÉϵÄÎļþ´´½¨Ò»¸özipÎļþ(config.zip)4 ¡£ÓÉÓÚÔçǰµ±ÎÒÃDZàÒët³ÌÐòʱÎÒÃÇʹÓÃÁ˲ÎÊý -addsrc£¬ÎÒÃÇÖ»ÐèÒª±àÒëµÄ.txeÎļþºÍÎÒÃǵÄXMLÅäÖÃ5 ¡£Èç¹ûÎÒÃÇʹÓÃÈκÎÊý¾Ý¿â£¬ÎÒÃÇÒ²½«ËüÃÇÌí¼Óµ½zip°üÖС£

import zipfile
import canlib
  
# Create Zip archive
with zipfile.ZipFile("config.zip", mode='w',
                     compression=zipfile.ZIP_DEFLATED) as zipf:
    # Adding files to zip archive
    zipf.write("config.xml")
    zipf.write("myCanGenerator.txe")
  
cl = canlib.canlib()
  
# We know that our device was connected to CANlib channel number 0
canlibChannel = 0
  
# Open the device and write the zip archive
ch = cl.openChannel(channel=canlibChannel)
# Since the SD card is formated using FAT, we should use
# a 8.3 filename as the target filename
ch.fileCopyToDevice("config.zip", "config.zip")
 
ch.close()

Áбí15£ºÊ¹ÓÃzip°üÏÂÔØÃ÷ÎÄÅäÖÃ

3.4 ¶ÁÈ¡½á¹û²¢±£´æµ½Îļþ

ÔÚÉ豸ÒѾ­ÔÚÏÖ³¡£¨¼´ÎÒÃÇÒѾ­Í¨¹ýCANÁ¬½ÓÆ÷¹©µç²¢Èýű¾ÔËÐУ©ÔËÐÐÖ®ºó£¬ÎÒÃÇ¿ÉÒÔÔٴν«ÎÒÃǵÄÉ豸Á¬½Óµ½ÎÒÃǵļÆËã»ú²¢¶ÁÈ¡¼Ç¼µÄÊý¾Ý¡£6 ΪÁ˱£´æÊý¾ÝÒÔ±¸½«À´Ê¹Óã¬ÎÒÃÇÏÖÔÚʹÓÃkme50¸ñʽ½«Êý¾ÝдÈëÎļþ¡£ÒÔºó¿ÉÒÔʹÓÃÔÆº£ÓÎÏ· MemoratorÅäÖù¤¾ßÖаüº¬µÄת»»Æ÷½«´Ë¸ñʽת»»Îª¶àÖÖ¸ñʽ¡£

ËùÓÐÈÕÖ¾ÎļþÖеĵÚÒ»¸öÌõÄ¿°üº¬ÓйØÒѼǼÉ豸µÄÐÅÏ¢¡£ÎÒÃÇÔÚÕâÀïÀûÓÃÕâÒ»ÓÅÊÆ£¬½«²úÆ·±àÂëºÍ²úÆ·ÐòÁкŵÄÒ»²¿·Ö·ÅÔÚÉú³ÉµÄ.kme50ÎļþµÄÃû³ÆÖС£

µ±´ÓÉ豸¶ÁÈ¡ËùÓÐÈÕÖ¾Îļþʱ£¬ÎÒÃÇɾ³ýÉ豸ÉϵÄÈÕÖ¾Îļþ£¬ÒÔ±ãΪеÄÈÕÖ¾¼Ç¼×öºÃ×¼±¸£¨ÖØÓÃÏàͬµÄÅäÖã©¡£

import glob
import os
  
ml = kvmlib.kvmlib()
  
# Since our firmware is v3.0 we should be using kvmDEVICE_MHYDRA_EXT
# as the device type.
deviceType = kvmlib.kvmDEVICE_MHYDRA_EXT
  
# We saw earlier that our device is connected to Card channel number 0
cardChannel = 0
  
# Directory to put the resulting files in
resultDir = "result"

=# Make sure the result directory exists and is empty
if os.path.isdir(resultDir):
    files = glob.glob(os.path.join(resultDir, "*"))
    for f in files:
        os.remove(f)
else:
    os.mkdir(resultDir)
os.chdir(resultDir)
 
# Open the device
ml.deviceOpen(memoNr=cardChannel, devicetype=deviceType)

try:
    # Mount the log area
    lioDataFormat = ml.deviceMountKmf()
    print "Lio Data Format v%s" % lioDataFormat
    # Verify that the LIO data format of the card corresponds to
    # the device type we used when opening the device
    if lioDataFormat != '5.0':
        print "Unexpected Lio Data Format:", lioDataFormat
        if lioDataFormat == '3.0':
            print("This log file can be read if you reopen the"
                  " device as kvmDEVICE_MHYDRA.")
        exit(1)
except kvmlib.kvmDiskNotFormated:
    print "SD card is not initialized..."
    exit(1)

# Read number of recorded logfiles
fileCount = ml.logFileGetCount()
print "Found %d file%s on card:" % (fileCount,
                                    "s" if fileCount > 1 else "")

# Loop through all logfiles and write their contents to .kme50 files
for fileIndx in range(fileCount):
    eventCount = ml.logFileMount(fileIndx)
    print "\tFile %3d: %10d events" % (fileIndx, eventCount)
    logEvent = ml.logFileReadEventLogFormat()
    #
    # The first logEvent contains device information
    memoEvent = logEvent.createMemoEvent()
    sn = memoEvent.serialNumber
    ean_lo = memoEvent.eanLo
    ean_sn = "%05x-%x_%d" % ((ean_lo >> 4) & 0xfffff, ean_lo & 0xf, sn)
    # Add EAN and serial number info to filename
    logfileName = "log_%s_%d.kme50" % (ean_sn, fileIndx)
    ml.kmeCreateFile(logfileName, kvmlib.kvmFILE_KME50)
    while logEvent is not None:
        # Write event to stdout
        print logEvent
        ml.kmeWriteEvent(logEvent)
        # Read next event
        logEvent = ml.logFileReadEventLogFormat()
    ml.kmeCloseFile()
  
# Delete all logfiles
ml.logFileDeleteAll()
  
# Close device
ml.close()

Áбí16£º¶ÁÈ¡¼Ç¼µÄÊý¾Ý²¢±£´æµ½.kme50Îļþ

ÔĶÁ²©ÎÄʹÓÃkvmlibºÍPython·ÖÎö¼Ç¼µÄÊý¾Ý £¬Á˽âÈçºÎʹÓÃkvmlib´ÓÉ豸¶ÁÈ¡Êý¾ÝµÄÁíÒ»¸öʾÀý¡£

3.5 ´ÓÉ豸¶ÁÈ¡ÅäÖÃ

֮ǰÎÒÃǽ«ÅäÖõĸ±±¾·ÅÔÚSD¿¨ÉϵÄconfig.zipÎļþÖУ¬ÎÒÃÇÏÖÔÚ¿ÉÒÔʹÓÃCANlib¶ÁÈ¡ËùÓÐÓû§Îļþ¡£È»ºóËù»ñÈ¡Îļþ¿ÉÒÔʹÓÃÖîÈç7-zipѹËõÈí¼þ´ò¿ª¡£7

import os

import canlib

cl = canlib.canlib()

# We already knew that our device was connected to CANlib channel number 0
canlibChannel = 0
# Open the device
ch = cl.openChannel(channel=canlibChannel)

# List files on device
numFiles = ch.fileGetCount()

if numFiles:
    for i in range(numFiles):
        name = ch.fileGetName(i)
        # Skip known system files
        if (os.path.splitext(name)[1].lower() == '.kmf'
                or name.lower() == 'param.lif'
                or name.lower() == 'database.bin'):
            print "Skipping %s" % name
        else:
            # Copy user files to PC
            print "Copying %s" % name
            ch.fileCopyFromDevice(name, name)

ch.close()

Áбí17£º´ÓÔÆº£ÓÎÏ·É豸¸´ÖÆÓû§Îļþ

Skipping PARAM.LIF
Skipping LOG00000.KMF
Skipping LOG00001.KMF
Skipping LOG00002.KMF
Skipping LOG00003.KMF
Skipping LOG00004.KMF
Skipping LOG00005.KMF
Skipping DATABASE.BIN
Copying CONFIG.ZIP

Òò´ËÕâÆª¹ØÓÚʹÓõͼ¶kvmlibµ÷ÓÃÅäÖÃÎÒÃǵÄÔÆº£ÓÎÏ· MemoratorÉ豸µÄÎÄÕµ½´Ë½áÊø¡£ÎÒÃǽ«ÔÚ±¾ÏµÁÐÎÄÕµÄÏÂһƪºÍ×îºóһƪÖУ¬½²ÊöÕë¶ÔÈç¹ûÎÒÃÇÖ»ÄÜ·ÃÎʲåÈëÉ豸µÄSD¿¨ËùÒª²ÉÈ¡µÄ²½Öè¡£

½Å×¢

1 ¸ü¶àÄÚÈݼû²©ÎÄÊÇCANlibͨµÀºÅ»¹ÊÇ¿¨ºÅ£¿

2 LIOÊý¾Ý¸ñʽÊǹØÓÚÈçºÎÔÚSD¿¨ÉÏ´æ´¢Êý¾ÝµÄ¹æ·¶¡£×îеÄLIOÊý¾Ý¸ñʽv5.0Äܹ»´¦ÀíCAN FD¿ÉÉú³ÉµÄ¸ü´óµÄÊý¾ÝÖ¡¡£

3 ÔçÓÚ3.0°æ±¾µÄ¹Ì¼þӦʹÓÃÉ豸ÀàÐÍkvmDEVICE.MHYDRA¡£

4 ÕâÀàËÆÓÚµ±Äú¹´Ñ¡¡°ÔÚ´ÅÅÌÉϱ£´æÅäÖúÍÊý¾Ý¿â¡±Ê±Ôƺ£ÓÎÏ· MemoratorÅäÖù¤¾ßËùÖ´ÐеIJÙ×÷¡£ È»ºó£¬¸Ã¹¤¾ß½«Ê¹ÓõÄÅäÖúÍÊý¾Ý¿âÎļþ²åÈëµ½ÎļþDATABASE.BINÖС£

5 ÔÚÉÏһƪÎÄÕÂÖУ¬ÔÚÅäÖÃÖÐÌí¼Ó½Å±¾ºÍ´¥·¢Æ÷¡£

6 ÎÒÃÇÓ¦¸ÃÒ²¿ÉÒÔÔÚÕâÀï²é¿´LIOÊý¾Ý¸ñʽ°æ±¾£¬²Î¿¼ÎÒÃÇÔçÏȵÄÓйØÓÚÈçºÎʵÏֵijõʼ»¯´úÂë¡£

7 7-zipÊÇÒ»¿îÓÃÓÚ´¦Àí´æµµµÄ¿ªÔ´WindowsʵÓóÌÐò£¬ÏêϸÐÅÏ¢Çë²ÎÔÄwww.7-zip.org¡£

Author Image

Magnus Carlsson

Margus CarlssonÊÇÔÆº£ÓÎÏ· AB¹«Ë¾µÄÈí¼þ¿ª·¢ÈËÔ±£¬´Ó2007ÄêÒÔÀ´Éî¶È²ÎÓëÁËÔÆº£ÓÎÏ·¹Ì¼þºÍÈí¼þµÄ¿ª·¢¡£Ëû»¹ÎªÔƺ£ÓÎÏ·µÄ¼¼Êõ²©¿Í׫дÁËÐí¶àÓÃÁ÷ÐеÄPythonÓïÑÔ±àдӦÓóÌÐòµÄÎÄÕ¡£

¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿