2020-12-20-python2.x和python3.x对比

print函数、字符串编码、除法、range和xrange、不等运算符、数据类型、文件操作、兼容2.x和3.x的案例

print函数

1)python2

print 2

2)python3

print(3)

字符串编码

1)python2

ASCii类型

2)python3

utf8


除法

1)floor除法//

python2和python3一致

2)一般除法/

python2中,对于整数相除,结果中会把小数点后的值忽略

python3中,对于整数相除,会先将两个整数转换成浮点数,再进行相除, 结果是浮点数


range和xrange

两者功能相似,python2中主要是xrange(迭代器实现),python3中主要是range


不等运算符

1)python2

可以用《》!=表示

2)python3

只可以用!=


数据类型

1)python3中去掉了long类型,只有int

2)python2的bytes类型和str无区别

3)python3中dic的keys(),items,values返回的是一个迭代器;iterkeys()被废弃,dic.has_key()用in替代


文件操作

1)打开文件

python2

if __name__ == "__main__":
    f = open("C:\Users\zhanghuan\Desktop\\123.txt",mode="r")
    lines = f.readlines()
    print lines
    f.close()

注意:不可以有encoding="utf8",会报错

python3

if __name__ == "__main__":
    f = open("C:\\Users\\zhanghuan\\Desktop\\123.txt",mode="r",encoding="utf8")
    lines = f.readlines()
    print(lines)
    f.close()

2)输入

python2

if __name__ == "__main__":
    a = raw_input()
    print  a

python3

if __name__ == "__main__":
    a = input()
    print(a)

兼容2.x和3.x的案例

# -- coding: utf-8 --

import logging
import json,os,re,socket,urllib,time,threading

IS_PYTHON2=True
try:
    # python2.X
    import BaseHTTPServer,urllib2,sys
    from urllib import quote
    from urlparse import urlparse
    from urlparse import parse_qs
    #from io import open
    BaseHTTPRequestHandler = BaseHTTPServer.BaseHTTPRequestHandler
    HTTPServer = BaseHTTPServer.HTTPServer
    try:
        reload(sys)
        sys.setdefaultencoding("utf8")
    except Exception as e:
        print(e)
    
except Exception as e:
    print(e)
    print("当前python3.x环境")
    IS_PYTHON2=False
    # python3.x
    from http.server import BaseHTTPRequestHandler, HTTPServer
    from urllib.parse import urlparse
    from urllib.parse import parse_qs
    from urllib.request import urlopen
    from urllib.parse import quote


class LogFactory():
    rdir = os.path.dirname(os.path.abspath(__file__))  # 获取上级目录的绝对路径
    log_dir = rdir + os.sep +'log'
    log_file_dir = log_dir + os.sep + 'record.log'

    @classmethod
    def check_dirs(self):
        if not os.path.exists(self.log_dir):
            os.mkdir(self.log_dir)
        if not os.path.exists(self.log_file_dir):
            if not IS_PYTHON2:
                fd = open(self.log_file_dir, mode="w",encoding='utf-8')
            else:
                fd = open(self.log_file_dir, mode="w")
            fd.close()

    @classmethod
    def get_logger(self):
        LogFactory.check_dirs()
        fh = logging.FileHandler(self.log_file_dir, encoding='utf-8')  # 创建一个文件流并设置编码utf8
        logger = logging.getLogger()  # 获得一个logger对象,默认是root
        logger.setLevel(logging.DEBUG)  # 设置最低等级debug
        fm = logging.Formatter("%(asctime)s --- %(message)s")  # 设置日志格式
        logger.addHandler(fh)  # 把文件流添加进来,流向写入到文件
        fh.setFormatter(fm)  # 把文件流添加写入格式
        return logger


# 请求对象
class Request():

    path = None
    queries = None
    body = None
    headers = None

    def __init__(self,obj):
        if not IS_PYTHON2:
            pathObj = urlparse(obj.path)
            self.path = pathObj.path
            self.queries = self.__handleQueriesToStandardMap(parse_qs(pathObj.query))
            self.headers = obj.headers
            if obj.headers['content-length'] != None:
                self.body = obj.rfile.read(int(obj.headers['content-length']))
        else:
            pathObj = urlparse(obj.path)
            self.path = pathObj.path
            self.queries = self.__handleQueriesToStandardMap(parse_qs(pathObj.query))
            self.headers = obj.headers
            data_lenth = self.headers.getheader('content-length', 0)
            if data_lenth != None:
                self.body = obj.rfile.read(int(data_lenth))

    # 将{key,['value']}转换成{key,value}
    def __handleQueriesToStandardMap(self,map):
        new_map = {}
        for item in map.keys():
            new_map.__setitem__(item,map.get(item)[0])
        return new_map

# 响应对象
class Response():

    obj = None

    def __init__(self,obj):
        self.obj = obj

    def do_response(self,byte_data):
        self.obj.send_response(200)
        self.obj.send_header("Content-Type", "text/json;charset=UTF-8")
        self.obj.end_headers()
        self.obj.wfile.write(byte_data)

class ProperitesUtil():
    @classmethod
    def load_from_file(self,filepath):
        properties = {}
        with open(filepath,'r') as f:
            for line in f:
                if line.find('=') > 0:
                    strs = line.replace('\n', '').split('=')
                    properties[strs[0]] = strs[1].replace("\r","")
        return properties

class NacosService():
    base_dir = os.getcwd()
    cfg = ProperitesUtil.load_from_file("%s%sconfig.properties"%(base_dir,os.sep))

    # 发出心跳
    def beat_to_nacos(self):
        nacos_ip = self.cfg.get("nacosAddr")
        local_ip = self.get_local_ip()
        port = self.cfg.get("serverPort")

        beat_arg = {"cluster": "c1", "ip": local_ip, "metadata": {}, "port": int(port), "scheduled": "true",
                    "serviceName": "nginx", "weight": 1}
        beat_ip = 'http://%s/nacos/v1/ns/instance/beat?serviceName=nginx&beat=%s' % (nacos_ip,quote(str(beat_arg)))
        while True:
            if IS_PYTHON2 == False:
                request = urllib.request.Request(url=beat_ip, method="PUT")
                try:
                    urlopen(request)
                    print("beat to nacos success", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
                    time.sleep(5)
                except Exception as e:
                    print("nacos connect failure")
                    print(e)
                    time.sleep(5)
                    print("trying to connect to " + beat_ip + " again ……")
            else:
                try:
                    request = urllib2.Request(beat_ip)
                    request.get_method = lambda:"PUT"
                    opener = urllib2.build_opener(urllib2.HTTPHandler)
                    opener.open(request)
                    print("beat to nacos success", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
                    time.sleep(5)
                except Exception as e:
                    print("nacos connect failure")
                    print(e)
                    time.sleep(5)
                    print("trying to connect to " + beat_ip + " again ……")


    # 获取本机ip
    def get_local_ip(self):
        # 获取配置文件中的信息

        ip = self.cfg.get("preferred-networks")
        if not self.valid_ip(ip):
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(('8.8.8.8', 80))
            ip = s.getsockname()[0]
        return ip

    # 验证ip的合法性
    def valid_ip(self,address):
        try:
            socket.inet_aton(address)
            result = re.findall("\d+\.\d+\.\d+\.\d+",address)
            if len(result) == 0:
                return False
            else:
                return True
        except:
            return False


class MainHandler(BaseHTTPRequestHandler):

    base_dir = os.getcwd()
    log = LogFactory.get_logger()

    def do_GET(self):
        req = Request(self)
        res = Response(self)
        self.log.info("access " + req.path)
        if req.path == "/https/disable":
            # 关闭ssl
            cfg = ProperitesUtil.load_from_file("%s%sconfig.properties"%(base_dir,os.sep))
            if os.path.exists(cfg.get("sslConfDir")):
                os.remove(cfg.get("sslConfDir"))
            res.do_response(self.dic_to_bytes({"status":200}))
        else:
            err_msg = "未定义该路径"
            self.log.info(err_msg)
            res.do_response(self.dic_to_bytes({"status": 500,"msg":err_msg}))


    def do_POST(self):
        req = Request(self)
        res = Response(self)
        self.headers
        self.log.info("access " + req.path)
        if req.path == '/https/enable':
            # 开启ssl
            cfg = ProperitesUtil.load_from_file("%s%sconfig.properties"%(base_dir,os.sep))
            data = json.loads(req.body)
            print(data)

            # 获取ssl端口
            port_num = data['port']

            # 获取ssl_certificate_file_name
            ssl_certificate = data['ssl_certificate']
            ssl_certificate_file_name = None if ssl_certificate =="" else "server" + ".crt"

            # 获取ssl_certificate_key_file_name
            ssl_certificate_key = data['ssl_certificate_key']
            ssl_certificate_key_file_name = None if ssl_certificate_key =="" else "server" + ".key"

            # 获取ssl_client_certificate_file_name
            ssl_client_certificate = data['ssl_client_certificate']
            ssl_client_certificate_file_name = None if ssl_client_certificate == "" else "CA" + ".crt"


            # 操作nginx配置文件
            modify_config_file = self.modify_config_file(ssl_certificate_file_name,
                                                         ssl_certificate_key_file_name,
                                                         ssl_client_certificate_file_name,port_num)

            print(ssl_certificate_file_name,ssl_certificate_key_file_name,ssl_client_certificate_file_name)

            if modify_config_file:
                # 写入密钥文件
                server_crt_path = cfg.get("nginxConfDir") + os.sep + "server.crt"
                server_key_path = cfg.get("nginxConfDir") + os.sep + "server.key"
                CA_crt_path = cfg.get("nginxConfDir") + os.sep + "CA.crt"

                self.write_to_file(server_crt_path,str(ssl_certificate))
                self.write_to_file(server_key_path, str(ssl_certificate_key))
                if ssl_client_certificate_file_name != None:
                    self.write_to_file(CA_crt_path, str(ssl_client_certificate))

                res.do_response(self.dic_to_bytes({"status":200}))
            else:
                err_msg = "出错了,可能原因:模板https配置文件不存在,传过来的参数不正确"
                self.log.info(err_msg)
                res.do_response(self.dic_to_bytes({"status": 500,"msg":err_msg}))
        else:
            err_msg = "未定义该路径"
            self.log.info(err_msg)
            res.do_response(self.dic_to_bytes({"status": 500,"msg":err_msg}))

    def do_PUT(self):
        req = Request(self)
        res = Response(self)
        err_msg = "未定义该路径"
        self.log.info(err_msg)
        res.do_response(self.dic_to_bytes({"status": 500, "msg": err_msg}))

    def do_DELETE(self):
        req = Request(self)
        res = Response(self)
        err_msg = "未定义该路径"
        self.log.info(err_msg)
        res.do_response(self.dic_to_bytes({"status": 500, "msg": err_msg}))

    def dic_to_bytes(self,dic):
        if not IS_PYTHON2:
            return bytes(json.dumps(dic), encoding="utf8")
        else:
            return bytes(json.dumps(dic)).encode("utf8")

    # 内容指定路径写入到文件
    def write_to_file(self,filename,content):

        if IS_PYTHON2:
            f1 = open(filename, mode='w')
            content = content.decode('utf8')
        else:
            f1 = open(filename, mode='w', encoding='utf8')
        f1.writelines(content)
        f1.close()

    def write_to_file_from_list(self,filename,list):
        if not IS_PYTHON2:
            with open(filename,mode='w',encoding="utf8") as f:
                for item in list:
                    f.write(item)
        else:
            with open(filename,mode='w') as f:
                for item in list:
                    f.write(item)

    def read_from_file(self,filename):
        if not IS_PYTHON2:
            with open(filename, 'r', encoding='utf8') as f:
                return f.readlines()
        else:
            with open(filename,'r') as f:
                return f.readlines()


    # 操作nginx配置文件
    def modify_config_file(self,ssl_certificate_file_name,ssl_certificate_key_file_name,ssl_client_certificate_file_name,port_num):

        # 参数检验
        if ssl_certificate_file_name == None or ssl_certificate_key_file_name == None or port_num == None:
            self.log.error("ssl_certificate_file_name,ssl_certificate_key_file_name,port_num"+"参数不合法")
            return False

        # 获取配置文件中的信息
        cfg = ProperitesUtil.load_from_file("%s%sconfig.properties"%(base_dir,os.sep))

        # 获取nginx配置文件模板路径
        template_https_conf_diir = "%s%stemplate%shttps.conf"%(self.base_dir,os.sep,os.sep)

        # 获取nginx配置文件路径
        https_conf_dir = cfg.get("sslConfDir")

        # 如果路径不存在,返回False
        if not os.path.exists(template_https_conf_diir):
            self.log.error("template_https_conf_diir路径不存在")
            return False

        # 将配置文件内容读取出来并替换
        content = self.read_from_file(template_https_conf_diir)
        for i in range(len(content)):
            ssl_certificate = re.findall("ssl_certificate\s+\w+\.\w+", content[i])
            ssl_certificate_key = re.findall("ssl_certificate_key\s+\w+\.\w+", content[i])
            ssl_client_certificate = re.findall("ssl_client_certificate\s+\w+\.\w+", content[i])
            port = re.findall("listen\s+\d+\s+ssl", content[i])

            # 标记
            mark = -1

            if len(ssl_certificate) != 0:
                content[i] = content[i].replace(ssl_certificate[0], "ssl_certificate "+ssl_certificate_file_name)
            if len(ssl_certificate_key) != 0:
                content[i] = content[i].replace(ssl_certificate_key[0], "ssl_certificate_key "+ssl_certificate_key_file_name)
                mark = i+1
            if mark != -1 and ssl_client_certificate_file_name != None:
                content.insert(mark,"    ssl_client_certificate "+ssl_client_certificate_file_name+"\n")
                mark = -1
            if len(port) != 0:
                content[i] = content[i].replace(port[0], "listen "+str(port_num)+" ssl")

        # 将修改后的配置文件写入
        self.write_to_file_from_list(cfg.get("sslConfDir"),content)
        return True





if __name__ == '__main__':

    # 获取配置文件
    base_dir = os.getcwd()
    cfg = ProperitesUtil.load_from_file("%s%sconfig.properties"%(base_dir,os.sep))
    port = cfg.get("serverPort")

    # 开启一个线程发出心跳
    nacosService = NacosService()
    t = threading.Thread(target=nacosService.beat_to_nacos)
    t.daemon = True
    t.start()

    server = HTTPServer(("0.0.0.0",int(port)), MainHandler)
    print("The server is already started at " + port)
    server.serve_forever()



config.properties

# 端口号
serverPort=8088
# 放置证书的地址,在nginx的conf目录下
nginxConfDir=C:\Users\zhanghuan\Desktop\test
# https相关的配置文件地址
sslConfDir=C:\Users\zhanghuan\Desktop\test\https.conf
# nacos服务的地址
nacosAddr=10.0.248.94:8848
# 本机ip,可不指定
preferred-networks=

另外创建一个template文件夹,放入nginx的https配置文件模板

posted @ 2024-03-22 17:12  SylvesterZhang  阅读(37)  评论(0)    收藏  举报