argparse参数及其结合套接字开发简单的聊天程序

310 阅读4分钟
argparse参数设置的方便之处在于在命令行直接给程序里面的参数赋值,风格看起来更加接近用户级的程序。

首先创建一个python文档,内容如下:

import argparse
parser=argparse.ArgumentParser()
parser.parse_args()
并且保存命名为test.py,保存在一个目录下面。
然后在命令行里面输入下面的命令:
C:\Users\18813421705xbx>text.py

C:\Users\18813421705xbx>text.py --help
usage: text.py [-h]

optional arguments:
  -h, --help  show this help message and exit
第一个打开文件的指令没有返回什么,但是加上“--help”之后,就打印出来一些东西。
再试一下下面的指令:
C:\Users\18813421705xbx>text.py --echo
usage: text.py [-h]
text.py: error: unrecognized arguments: --echo
报错,显示无法识别声明。
接下来给text.py添加一些东西:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("get",help="help getting somgthing")
parser.parse_args()
下面再试一下打印刚刚加进去的东西:
C:\Users\18813421705xbx>text.py get --help
usage: text.py [-h] get

positional arguments:
  get         help getting somgthing

type关键字参数

type关键字在于告诉argparse,接收参数的时候以什么样的形式接收,或者把参数理解为什么类型。
试一下下面的修改:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("squre",help="help getting somgthing",type=int)
print((parser.parse_args().squre)**2)
运行一下命令行代码:
C:\Users\18813421705xbx>text.py 4
16
但是如果不加上type关键字参数,会默认把参数认为是字符串,会引起类型错误:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("squre",help="help getting somgthing")
print((parser.parse_args().squre)**2)
C:\Users\18813421705xbx>text.py 4
Traceback (most recent call last):
  File "C:\Users\18813421705xbx\text.py", line 4, in <module>
    print((parser.parse_args().squre)**2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
因为我们提前告诉argparse,4是一个int而不是一个str,因此int进行pow()运算的时候是不会报错的。
可以看一下没有加type关键字时候的参数的类型:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("squre",help="help getting somgthing")
print(type(parser.parse_args().squre))
C:\Users\18813421705xbx>text.py squre
<class 'str'>

可选参数:“--”

import argparse
parser=argparse.ArgumentParser()
parser.add_argument("--squre",help="help getting somgthing")
print(parser.parse_args().squre)
这样无论给squre赋值什么都可以打印出来,并且注意在初始化参数的时候,一定要给squre赋值,不然就报错。
C:\Users\18813421705xbx>text.py --squre 12
12

C:\Users\18813421705xbx>text.py --squre
usage: text.py [-h] [--squre SQURE]
text.py: error: argument --squre: expected one argument
但是可以通过关键字参数action来指定参数的值:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("--squre",help="help getting somgthing",action="store_true")
print(parser.parse_args().squre)
C:\Users\18813421705xbx>text.py --squre
True
这样如果不传入--squre参数,squre就默认是False。而且就算传入该参数,也不能再指定值。
在写完可选参数之后,可以在前面加上一个代表该参数的缩写,以“-”开头。
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("-s","--squre",help="help getting somgthing",action="store_true")
print(parser.parse_args().squre)

choice关键字参数:

choice关键字参数用一个列表表示,限制参数的赋值范围:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("-s","--squre",help="help getting somgthing",choices=[0,1,2],type=int)
print(parser.parse_args().squre)
C:\Users\18813421705xbx>text.py -s 1
1

C:\Users\18813421705xbx>text.py -s 4
usage: text.py [-h] [-s {0,1,2}]
text.py: error: argument -s/--squre: invalid choice: 4 (choose from 0, 1, 2)

action关键字设置为:count

前面已经提到了action关键字,当设置值为:store_true的时候,会默认设置可选参数的值为true;当设置action关键字的值为count的时候,可以计算参数里面的可选参数的数目并且赋值给可选参数:
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("-s","--squre",help="help getting somgthing",action='count')
print(type(parser.parse_args().squre))
print(parser.parse_args().squre)
输出是这样的:
C:\Users\18813421705xbx>text.py -sss
<class 'int'>
3

default参数:

import argparse
parser=argparse.ArgumentParser()
parser.add_argument("-s","--squre",help="help getting somgthing",action='count',default=0)
print(type(parser.parse_args().squre))
print(parser.parse_args().squre)
运行:
C:\Users\18813421705xbx>text.py
<class 'int'>
0

结合套接字开发简单的UDP交互程序

import argparse
import socket
import time
def server(port):
    sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sock.bind(('127.0.0.1',port))
    print('the server is listening at{}'.format(sock.getsockname()))
    while True:
        data,address=sock.recvfrom(65535)
        text=data.decode('ascii')
        print('the client from {} is saying {!r}'.format(address,text))
        text_feedback='Your data is {} byte long'.format(len(data))
        data_feedback=text_feedback.encode('ascii')
        sock.sendto(data_feedback,address)

def client(port):
    sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        text = input('input the message you want to send:')
        data = text.encode('ascii')
        sock.sendto(data,('127.0.0.1',port))
        print('the os assigs the address of {} to me'.format(sock.getsockname()))
        data_re,address_ser=sock.recvfrom(65535)
        text_re=data_re.decode('ascii')
        print('the server from {} says {}'.format(address_ser,text_re))

if __name__=='__main__':
    parser=argparse.ArgumentParser()
    parser.add_argument('role',choices=['client','server'],help='select which function to run')
    parser.add_argument('--port',type=int,default=1060,help='UDP port,default is 1060')

    args=parser.parse_args()
    if args.role=='client':
        client(args.port)
    if args.role=='server':
        server(args.port)