-
装饰器:本质就是函数,功能是为其他函数添加附加功能原则: 1、不修改被修饰函数的源代码 2、不修改被修饰函数的调用方式装饰器 = 高阶函数 + 函数嵌套 + 闭包 二、高阶函数高阶函数定义: 1、函数接收的参数是一个函数 2、函数的返回值是一个函数名 3、满足上述条件任意一个,都可以称为高阶函数test 函数是高阶函数,接受了一个foo 作为参数123456789101112import timedef foo(): time.sleep(3) print("sleep 3s") def test(func): start_time = time.time() func() stop_time = time.time() print("函数的运行时间是: %s" % (stop_time - start_time)) test(foo)timer 是一个高阶函数,这个函数返回值是一个函数1234567891011121314import timedef foo(): time.sleep(3) print("sleep 3s") def timer(func): start_time = time.time() func() stop_time = time.time() print("执行时间{}".format(stop_time - start_time)) return funcfoo = timer(foo)foo()# 结果: 多运行了一次 三、函数嵌套在函数里面定义函数,变量的作用域和生存周期不变。12345678910def father(name): print("father name: %s" % name) def son(): print("son name: %s" % name) son()father("xu1") # 结果:# father name: xu1# son name: xu1
-
# 网络爬虫是如何工作的  # 网络爬虫能做什么 1.搜索引擎:谷歌 百度 2.信息收集:新闻资源聚合 3.数据分析:商品价格比较、股票量化交易 4.图片抓取:抓取特定类型的图片,可用于个人收藏、AI图像分析 # 为什么使用python编写爬虫 1.Python编程语言语法简洁,易于学习,快速上手; 2.Python有成熟的爬虫生态,在抓取网页本身和网页抓取后的处理都有丰富的框架和库可用(如 Beautiful Soup框架、 Urlib2Requests2和库等),编写爬虫不必从零开始; 3.Python在处理数据方面有天然的优势,可以把 Python爬虫与后续的机器学习、数据可视化无缝对接。 # 什么是python Python是一种面向对象的解释型计算机程序设计语言。 1.免费、开源; 2.多种平台、可扩展、不区分操作系统; 3.语法简洁清晰、容易上手; 4.语法表达优美易读、利用缩进表示语句块的开始和退出; 5.支持模块和包、有极为丰富、功能强大的库; 6.在人工智能、科学计算、图形技术、动画、游戏等行业被广泛使用。 # 什么是HTML 1.HTML(HyperText Markup Language)是一种用于创建网页的超文本标记语言; 2.HTML可以构建WEB站点,HTML运行在浏览器上,由浏览器来解析  ## 抓取图片和文字需要用到的一些标签  # HTTP协议 HTTP (HyperText transfer protocol )超文本传输协议)是一个基于请求与响应模式的应用层的协议,通常是基于TCP的连接方式; 1.简单快速:客户请求时只需传送请求方法和路径,程序规模小,因而通信速度很快; 2.灵活:HTTP允许传输任意类型的数据对象; 3.无连接:服务端每次只处理一个请求,完成即断开,节省传输时间; # HTTP请求  # HTTP响应  # 爬虫抓取图片方案对比  # 弹性云服务器ECS 弹性云服务器(Elastic Cloud Server)是一种可随时自助获取、可弹性伸缩的云服务器,帮助用户打造可靠、安全、灵活、高效的应用环境。 ECS的主要特性如下: 1.数据可靠:可弹性扩展的虚拟块存储服务,高数据可靠性,高吞吐能力; 2.弹性易用:提供控制台、远程终端和A等多种管理方式,给您完全管理权限; 3.规格丰富:多类型、多规格、多镜像; 4.多维监控:提供开放性的云监控服务平台提供资源的实时监控、告警、通知等服务。 # 关系型数据库RDS  # 对象存储服务OBS  ## 使用OBS存储爬取内容的优势  # 实验过程中用到的主要命令 ## SQL建表命令  ## 新建项目文件夹 1.cd Desktop 2.scrapy startproject vmall_spider 3.cd vmall_spider 4.scrapy genspider -t crawl vmall "vmall.com" ## 下载python安装包 wget https://sandbox-experiment-resource-north-4.obs.cn-north-4.myhuaweicloud.com/python-spider-rds/Python-3.5.5.tgz ## 解压python安装包 tar -zxvf Python-3.5.5.tgz && cd Python-3.5.5/ ## 安装python make && make install ## 升级pip pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip ## 退出登录状态 exit ## 加权限 chmod 777 ## 查看AK和SK内容命令 vi credentials.csv
-
背景:pytest以特定规则搜索测试用例,所以测试用例文件、测试类以及类中的方法、测试函数这些命名都必须符合规则,才能被pytest搜索到并加入测试运行队列中。默认搜索规则:如果pytest命令行有指定目录,则从该目录中开始查找测试用例文件,如果没有指定,则从当前运行目录开始查找文件。注意,该查找是递归查找,子目录中的文件也会被查找到。并不是能够查找到目录下的所有文件,只有符合命名规则的文件才会被查找。默认规则是以test_开头或者以_test结尾的.py文件。在测试文件中查找Test开头的类,以及类中以test_开头的方法,查找测试文件中test_开头的函数。测试用例默认命名规则除非pytest命令指定到测试用例文件,否则测试用例文件命名应该以 test_开头或者以_test结尾。测试函数命名,测试类的方法命名应该以test_开头。测试类命名应当以Test开头。tips: 测试类的不应该有构造函数。笔者习惯装测试用例的文件夹,测试用例文件,测试函数,类中的测试方法都以test_开头。建议保持一种统一的风格。示例:12345678910111213141516171819202122232425262728293031323334# func.pydef add(a,b): return a+b # ./test_case/test_func.pyimport pytestfrom func import * class TestFunc: #def __init__(self): #self.a = 1 def test_add_by_class(self): assert add(2,3) == 5 def test_add_by_func(): assert add(4,6) == 10 '''# stdout:============================= test session starts =============================platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1rootdir: D:\Python3.7\project\pytestplugins: allure-pytest-2.8.9, rerunfailures-8.0collected 2 items test_case\test_func.py .. [100%] ============================== 2 passed in 0.04s ==============================[Finished in 1.3s]######################################################################'''测试结果中,test_case\test_func.py … 。两个点号代表两个测试用例。错误示范,当测试类有构造函数时:12345678910111213141516171819202122232425262728293031323334353637383940# func.pydef add(a,b): return a+b # ./test_case/test_func.pyimport pytestfrom func import * class TestFunc: def __init__(self): self.a = 1 def test_add_by_class(self): assert add(2,3) == 5 def test_add_by_func(): assert add(4,6) == 10 '''# stdout:============================= test session starts =============================platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1rootdir: D:\Python3.7\project\pytestplugins: allure-pytest-2.8.9, rerunfailures-8.0collected 1 item test_case\test_func.py . [100%] ============================== warnings summary ===============================test_case\test_func.py:4 D:\Python3.7\project\pytest\test_case\test_func.py:4: PytestCollectionWarning: cannot collect test class 'TestFunc' because it has a __init__ constructor (from: test_case/test_func.py) class TestFunc: -- Docs: https://docs.pytest.org/en/latest/warnings.html======================== 1 passed, 1 warning in 0.04s =========================[Finished in 1.4s]######################################################################'''会报错,pytest只能找到test_开头的函数,但是不能找到Test开头的含有构造函数的测试类。自定义测试用例命名规则如果因为某种需要,需要使用其他命名规则命名的测试文件、测试函数、测试类以及测试类的方法,可以通过pytest.ini配置文件做到。在测试系统的顶层目录创建pytest.ini文件,在pytest.ini文件中写入如下配置:123456789[pytest]# 更改测试文件命名规则python_files = HG* # 更改测试类命名规则python_classes = HG* # 更嗨测试函数命名规则python_functions = HG*示例:1234567891011121314151617181920212223242526272829303132333435# func.pydef add(a,b): return a+b # ./test_case/HG_func.pyimport pytestfrom func import * class HGFunc: #def __init__(self): #self.a = 1 def HG_add_by_class(self): assert add(2,3) == 5 def HG_add_by_func(): assert add(4,6) == 10 '''stdout:============================= test session starts =============================platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.execachedir: .pytest_cacherootdir: D:\Python3.7\project\pytest, inifile: pytest.iniplugins: allure-pytest-2.8.9, rerunfailures-8.0collecting ... collected 2 items test_case/HG_func.py::HGFunc::HG_add_by_class PASSED [ 50%]test_case/HG_func.py::HG_add_by_func PASSED [100%] ============================== 2 passed in 0.03s ==============================[Finished in 1.3s]'''Tips:pytest.ini是可以改变pytest运行方式的配置文件,但是正常情况下,测试系统里根本不需要存在pytest.ini文件,我们使用默认的运行方式即可工作。pytest.ini还有许多其他个性化配置,当有需要时,可以在自动化测试项目的顶层目录里创建pytest.ini文件,添加配置,达到个性化运行的目的。
-
【Python编程创造营】第三阶段正在进行中为了巩固大家的学习成果,紧跟学习进度请将需要完成的每章随堂测验内容按要求回复到本帖下方按要求格式回复即可获得积分累计阶段奖品,还能有机会获得附加幸运奖哦~打卡时间2021.04.16-2021.05.05 23:59打卡要求在本帖中,回复对应章节的随堂测验并提交截图 ↓回复格式:自己的华为云ID+课堂章节序号+课程完成截图(露出右上角华为云ID,随堂测验为绿色对勾完成状态)回复示例:华为云帐号:grandmaster+第一章 程序员的好助手-Python奖励方式每章节每次有效打卡可获得2积分阶段学习将以积分排行榜的形式,对前300名小伙伴进行奖励!此外还有附加奖励,每2周在提交随堂测验的用户中随机抽取10位送出幸运奖奖励华为云定制敏捷扑克牌 积分排行榜奖品 活动注意事项 由于本帖回复内容为随堂测试结果,已设置回帖仅版主可见1. 学习任务提交后,小助手会在本阶段学习周期内,按序完成审核,并增加活动积分;2. 本次活动通过完成每章习题打卡任务,可获得的积分上限为2分/每章节;3. 请务必按照上述要求提交内容,以免影响积分增加;4. 若积分值相同则以完成学习任务的时间先后排序,其中任务完成时间的判定优先级为:结业考核>问答官排位赛>每周学习笔记>每章随堂测验打卡5. 其他积分获取方式请查看活动社群公告。想了解更多关于课程内容请移步主帖:https://bbs.huaweicloud.com/forum/thread-108015-1-1.html除了本帖任务,其他学习任务可以通过以下链接进行查看:查看学习笔记打卡帖:https://bbs.huaweicloud.com/forum/thread-121155-1-1.html查看问答官排位赛活动帖:https://bbs.huaweicloud.com/forum/thread-121148-1-1.html
-
【Python编程创造营】第三阶段正在进行中为了巩固大家的学习成果,紧跟学习进度请按需要完成的每周读书笔记内容按要求回复到本帖下方按要求格式回复即可获得积分累计阶段奖品,还能有机会获得附加幸运奖哦~打卡时间2021.04.16-2021.05.05 23:59打卡要求在本帖中,回复每周读书笔记和心得 ↓回复格式:华为云ID+第几周笔记+笔记内容,并分享些读书心得(字数≥200字)回复示例如下:奖励方式每周每次有效打卡可获得5积分阶段学习将以积分排行榜的形式,对前300名小伙伴进行奖励!此外还有附加奖励,每2周在提交读书笔记的用户中随机抽取10位送出幸运奖奖励华为云定制文件收纳袋 积分排行榜奖品 活动注意事项 由于本帖回复内容为随堂测试结果,已设置回帖仅版主可见1. 学习任务提交后,小助手会在本阶段学习周期内,按序完成审核,并增加活动积分;2. 本次活动通过完成提交学习笔记任务,可获得的积分上限为5分/每周;3. 请务必按照上述要求提交内容,以免影响积分增加;4. 若积分值相同则以完成学习任务的时间先后排序,其中任务完成时间的判定优先级为:结业考核>问答官排位赛>每周学习笔记>每章随堂测验打卡5. 其他积分获取方式请查看活动社群公告。想了解更多关于课程内容请移步主帖:https://bbs.huaweicloud.com/forum/thread-108015-1-1.html除了本帖任务,其他学习任务可以通过以下链接进行查看:查看章节测验打卡帖:https://bbs.huaweicloud.com/forum/thread-121161-1-1.html查看问答官排位赛活动帖:https://bbs.huaweicloud.com/forum/thread-121148-1-1.html
-
【Python编程创造营】第三阶段已开课我们也特别为大家设置了【学习任务打卡】环节为的就是让大家巩固学习成果,紧跟学习进度现推出【问答官排位赛】,请各位同学详细查看本帖说明按要求格式回复即可获得积分累计阶段奖品,还能有机会获得附加幸运奖哦~ 活动时间:2021.04.16-2021.05.05.23:59 参与方式:用户在本帖里发布自己在Python学习中产生的疑惑或实践问题,其他用户可通过在楼层下评论参与回答。 参与规则:1. 同一ID不可自问自答;2. 同一ID可回复其他同一ID问题数量需≤3次,如,A最多可回答B的三个问题,但A可回答B、C、D、E、F等多人次问题。3. 每个人最多可发布10个有效问题,不可重复,不可灌水。4. 每个ID回答次数不设上限,但是否被采纳要依据专家评审后的结果。 活动奖励:由专家经过评审:(有效提问积分每周更新)◎每个有效提问可获得2积分。每周由专家评定,更新排行榜,上限为10个问题,不得灌水,不得与他人显示,问题具有意义,占楼无效。有效提问示例:无效提问示例:◎同一问题下确定一名最佳答案。阶段末共选出5名最佳答案,被采纳的最佳回答者可获得10积分。(最佳问答官阶段末评出,积分阶段末统计)本阶段五位最佳答题官已产生,分别是@zekelove@壹贰叁@Ania@蜡笔不辣@Felix666 恭喜这5位小伙伴可以获得额外10积分哦~积分排行榜奖品 活动注意事项1. 学习任务提交后,小助手会在本阶段学习周期内,按序完成审核,并增加活动积分;2. 本次活动通过完成提交问答官问题,可获得的积分上限为2分/每个有效提问,每人最多10个有效提问;3. 请务必按照上述要求提交内容,以免影响积分增加;4. 若积分值相同则以完成学习任务的时间先后排序,其中任务完成时间的判定优先级为:结业考核>问答官排位赛>每周学习笔记>每章随堂测验打卡5. 其他积分获取方式请查看活动社群公告。想了解更多关于课程内容请移步主帖:https://bbs.huaweicloud.com/forum/thread-108015-1-1.html除了本帖任务,其他学习任务可以通过以下链接进行查看:查看章节测验打卡帖:https://bbs.huaweicloud.com/forum/thread-121161-1-1.html查看每周读书笔记打卡帖:https://bbs.huaweicloud.com/forum/thread-121155-1-1.html
-
Django 提供一个了“信号分发器”机制,允许解耦的应用在框架的其它地方发生操作时会被通知到。 通俗而讲Django信号的工作原理就是当某个事件发生的时候会发出一个信号(signals), 而监听这个信号的函数(receivers)就会立即执行。Django信号的应用场景很多,尤其是用于不同模型或程序间的联动。常见例子包括创建User对象实例时创建一对一关系的UserProfile对象实例,或者每当用户下订单时触发给管理员发邮件的动作。今天小编我就分享下如何正确使用Django的信号(signals)。 Django信号的一个简单例子假设我们有一个如下User模型,我们希望每次有User对象新创建时都打印出有新用户注册的提示信息,我们可以使用Django信号(signals)轻松实现。我们的信号发送者sender是User模型,每当User模型执行post_save动作时就会发出信号。此时我们自定义的create_user函数一旦监听到User发出的post_save信号就会执行,先通过if created判断对象是新创建的还是被更新的;如果对象是新创建的,就会打印出提示信息。# models.py12345678910111213141516from django.db import models from django.db.models import signalsfrom django.dispatch import receiver class User(models.Model): name = models.CharField(max_length=16) gender = models.CharField(max_length=32, blank=True) def create_user(sender, instance, created, **kwargs): if created: print("New user created!") post_save.connect(create_user, sender=User)在上例中我们使用了信号(post_save)自带的connect的方法将自定义的函数与信号发出者(sender)User模型进行了连接。在实际应用中一个更常用的方式是使用@receiver装饰器实现发送者与监听函数的连接,如下所示。@receiver(post_save, sender=User)读起来的意思就是监听User模型发出的post_save信号。123456789101112131415from django.db import models from django.db.models.signals import post_savefrom django.dispatch import receiver class User(models.Model): name = models.CharField(max_length=16) gender = models.CharField(max_length=32, blank=True) @receiver(post_save, sender=User)def create_user(sender, instance, created, **kwargs): if created: print("New user created!") 利用Django信号实现不同模型的联动更新我们再来看一个复杂一点的例子。我们有一个Profile模型,与User模型是一对一的关系。我们希望创建User对象实例时也创建Profile对象实例,而使用post_save更新User对象时不创建新的Profile对象。这时我们就可以自定义create_user_profile和save_user_profile两个监听函数,同时监听sender(User模型)发出的post_save信号。由于post_save可同时用于模型的创建和更新,我们用if created这个判断来加以区别。12345678910111213141516from django.db import modelsfrom django.db.models.signals import post_savefrom django.dispatch import receiver class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) birth_date = models.DateField(null=True, blank=True) @receiver(post_save, sender=User)def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User)def save_user_profile(sender, instance, **kwargs): instance.profile.save() Django常用内置信号之前的例子中我们使用的都是post_save信号,即在模型调用save()方法后才发送信号。Django其它常用内置信号还包括:django.db.models.signals.pre_save & post_save在模型调用 save()方法之前或之后发送。django.db.models.signals.pre_init& post_init在模型调用_init_方法之前或之后发送。django.db.models.signals.pre_delete & post_delete在模型调用delete()方法或查询集调用delete() 方法之前或之后发送。django.db.models.signals.m2m_changed在模型多对多关系改变后发送。django.core.signals.request_started & request_finished Django建立或关闭HTTP 请求时发送。 如何正确放置Django信号的监听函数代码在之前案例中,我们将Django信号的监听函数写在了models.py文件里。当一个app的与信号相关的自定义监听函数很多时,此时models.py代码将变得非常臃肿。一个更好的方式把所以自定义的信号监听函数集中放在app对应文件夹下的signals.py文件里,便于后期集中维护。假如我们有个account的app,包含了User和Pofile模型,我们不仅需要在account文件夹下新建signals.py,还需要修改account文件下apps.py和__init__.py,以导入创建的信号监听函数。# account/signals.py123456789101112131415161718192021from django.db.models.signals import post_savefrom django.dispatch import receiverfrom .models import User, Profile @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()# account/apps.py1234567from django.apps import AppConfig class AccountConfig(AppConfig): name = 'account' def ready(self): import account.signals# account/__init__.py1default_app_config = 'account.apps.AccountConfig'
-
1、not关键词可以反转一个布尔值。12345>>> not TrueFalse>>>>>> not 1 > 0False2、当使用if语句和while语句时,条件的结果会发生逆转。not关键字可以用于if语句:12if not 条件:代码块当条件不满足时,上述if语句执行代码块,但当条件满足时,它们不执行,因为not关键取反了结果。知识点扩展:python中的not具体表示是什么:在python中not是逻辑判断词,用于布尔型True和False,not True为False,not False为True,以下是几个常用的not的用法:(1) not与逻辑判断句if连用,代表not后面的表达式为False的时候,执行冒号后面的语句。比如:123a = Falseif not a: (这里因为a是False,所以not a就是True)print “hello”这里就能够输出结果hello(2) 判断元素是否在列表或者字典中,if a not in b,a是元素,b是列表或字典,这句话的意思是如果a不在列表b中,那么就执行冒号后面的语句,比如:1234a = 5b = [1, 2, 3]if a not in b:print “hello”这里也能够输出结果hellonot x 意思相当于 if x is false, then True, else False代码中经常会有变量是否为None的判断,有三种主要的写法:第一种是if x is None;第二种是 if not x:;第三种是if not x is None(这句这样理解更清晰if not (x is None))
-
客户端:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175from tkinter import *from tkinter.messagebox import *import socketimport threadingimport os # 主程序root = Tk()root.title("网络五子棋v2.0--UDP客户端")imgs = [PhotoImage(file='./images/BlackStone.png'), PhotoImage(file='./images/WhiteStone.png')]turn = 0MyTurn = -1 # 画对方棋子def drawOtherChess(x, y): global turn img1 = imgs[turn] cv.create_image((x * 40 + 20, y * 40 + 20), image=img1) cv.pack() maps[x][y] = str(turn) # 换下一方走棋 if turn == 0: turn = 1 else: turn = 0 # 发送消息def sendMessage(position): global s s.sendto(position.encode(), (host, port)) # 退出函数def callExit(event): position = "exit|" sendMessage(position) os.exit() # 走棋函数def callback(event): global turn global MyTurn if MyTurn == -1: MyTurn = turn else: if MyTurn != turn: showinfo(title="提示", message="还没轮到自己走棋") return # print("clicked at",event.x,event.y) x = event.x // 40 y = event.y // 40 print("clicked at", x, y, turn) if maps[x][y] != " ": showinfo(title="提示", message="已有棋子") else: img1 = imgs[turn] cv.create_image((x * 40 + 20, y * 40 + 20), image=img1) cv.pack() maps[x][y] = str(turn) position = str(x) + ',' + str(y) sendMessage("move|" + position) print("客户端走的位置", position) label1["text"] = "客户端走的位置" + position # 输出输赢信息 if win_lose(): if turn == 0: showinfo(title="提示", message="黑方你赢了") sendMessage("over|黑方你赢了!") else: showinfo(title="提示", message="白方你赢了!") sendMessage("over|白方你赢了!") # 换下一方走棋: if turn == 0: turn = 1 else: turn = 0 # 画棋盘def drawQiPan(): # 画棋盘 for i in range(0, 15): cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2) for i in range(0, 15): cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2) cv.pack() # 输赢判断def win_lose(): a = str(turn) print("a=", a) for i in range(0, 11): for j in range(0, 11): if maps[i][j] == a and maps[i + 1][j + 1] == a and maps[i + 2][j + 2] == a and maps[i + 3][j + 3] == a and \ maps[i + 4][j + 4] == a: print("x=y轴上形成五子连珠") return True for i in range(4, 15): for j in range(0, 11): if maps[i][j] == a and maps[i - 1][j + 1] == a and maps[i - 2][j + 2] == a and maps[i - 3][j + 3] == a and \ maps[i - 4][j + 4] == a: print("x=-y轴上形成五子连珠") return True for i in range(0, 15): for j in range(4, 15): if maps[i][j] == a and maps[i][j - 1] == a and maps[i][j - 2] == a and maps[i][j - 2] == a and maps[i][ j - 4] == a: print("Y轴上形成了五子连珠") return True for i in range(0, 11): for j in range(0, 15): if maps[i][j] == a and maps[i + 1][j] == a and maps[i + 2][j] == a and maps[i + 3][j] == a and maps[i + 4][ j] == a: print("X轴形成五子连珠") return True return False # 接受消息def receiveMessage(): # 接受消息 global s while True: data = s.recv(1024).decode('utf-8') a = data.split("|") if not data: print('server has exited!') break elif a[0] == 'exit': print('对方退出!') label1["text"] = '对方退出!游戏结束!' elif a[0] == 'over': print('对方赢信息!') label1["text"] = data.split("|")[0] showinfo(title="提示", message=data.split("|")[1]) elif a[0] == 'move': print('received:', data) p = a[1].split(",") x = int(p[0]) y = int(p[1]) print(p[0], p[1]) label1["text"] = "服务器走的位置" + p[0] + p[1] drawOtherChess(x, y) s.close() # 启动线程接受客户端消息def startNewThread(): thread = threading.Thread(target=receiveMessage, args=()) thread.setDaemon(True) thread.start() if __name__ == '__main__': # 主程序 maps = [[" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "] for y in range(15)] cv = Canvas(root, bg='green', width=610, height=610) drawQiPan() cv.bind("<Button-1>", callback) cv.pack() label1 = Label(root, text="客户端...") label1.pack() button1 = Button(root, text="退出游戏") button1.bind("<Button-1>", callExit) button1.pack() # 创建UDP s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) port = 8000 host = 'localhost' pos = 'join|' sendMessage(pos) startNewThread() root.mainloop()
-
服务器端:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183import osimport socketimport threading from tkinter import *from tkinter.messagebox import * def drawQiPan(): for i in range(0, 15): cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2) for i in range(0, 15): cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2) cv.pack() # 走棋函数def callPos(event): global turn global MyTurn if MyTurn == -1: # 第一次确认自己的角色 MyTurn = turn else: if MyTurn != turn: showinfo(title="提示", message="还没轮到自己下棋") return # print("clicked at",event.x,event.y,true) x = event.x // 40 y = event.y // 40 print("clicked at", x, y, turn) if maps[x][y] != " ": showinfo(title="提示", message="已有棋子") else: img1 = images[turn] cv.create_image((x * 40 + 20, y * 40 + 20), image=img1) cv.pack() maps[x][y] = str(turn) pos = str(x) + "," + str(y) sendMessage("move|" + pos) print("服务器走的位置", pos) label1["text"] = "服务器走的位置" + pos # 输出输赢信息 if win_lose(): if turn == 0: showinfo(title="提示", message="黑方你赢了") sendMessage("over|黑方你赢了") else: showinfo(title="提示", message="白方你赢了") sendMessage("over|白方你赢了") # 换下一方走棋 if turn == 0: turn = 1 else: turn = 0 # 发送消息def sendMessage(pos): global s global addr s.sendto(pos.encode(), addr) # 退出函数def callExit(event): pos = "exit|" sendMessage(pos) os.exit() # 画对方棋子def drawOtherChess(x, y): global turn img1 = images[turn] cv.create_image((x * 40 + 20, y * 40 + 20), image=img1) cv.pack() maps[x][y] = str(turn) # 换下一方走棋 if turn == 0: turn = 1 else: turn = 0 # 判断整个棋盘的输赢def win_lose(): a = str(turn) print("a=", a) for i in range(0, 11): for j in range(0, 11): if maps[i][j] == a and maps[i + 1][j + 1] == a and maps[i + 2][j + 2] == a and maps[i + 3][j + 3] == a and \ maps[i + 4][j + 4] == a: print("x=y轴上形成五子连珠") return True for i in range(4, 15): for j in range(0, 11): if maps[i][j] == a and maps[i - 1][j + 1] == a and maps[i - 2][j + 2] == a and maps[i - 3][j + 3] == a and \ maps[i - 4][j + 4] == a: print("x=-y轴上形成五子连珠") return True for i in range(0, 15): for j in range(4, 15): if maps[i][j] == a and maps[i][j - 1] == a and maps[i][j - 2] == a and maps[i][j - 2] == a and maps[i][ j - 4] == a: print("Y轴上形成了五子连珠") return True for i in range(0, 11): for j in range(0, 15): if maps[i][j] == a and maps[i + 1][j] == a and maps[i + 2][j] == a and maps[i + 3][j] == a and maps[i + 4][ j] == a: print("X轴形成五子连珠") return True return False # 输出map地图def print_map(): for j in range(0, 15): for i in range(0, 15): print(maps[i][j], end=' ') print('w') # 接受消息def receiveMessage(): global s while True: # 接受客户端发送的消息 global addr data, addr = s.recvfrom(1024) data = data.decode('utf-8') a = data.split("|") if not data: print('client has exited!') break elif a[0] == 'join': # 连接服务器的请求 print('client 连接服务器!') label1["text"] = 'client连接服务器成功,请你走棋!' elif a[0] == 'exit': print('client对方退出!') label1["text"] = 'client对方退出,游戏结束!' elif a[0] == 'over': print('对方赢信息!') label1["text"] = data.split("|")[0] showinfo(title="提示", message=data.split("1")[1]) elif a[0] == 'move': print('received:', data, 'from', addr) p = a[1].split(",") x = int(p[0]) y = int(p[1]) print(p[0], p[1]) label1["text"] = "客户端走的位置" + p[0] + p[1] drawOtherChess(x, y) s.close() def startNewThread(): # 启动新线程来接受客户端消息 thread = threading.Thread(target=receiveMessage, args=()) thread.setDaemon(True) thread.start() if __name__ == '__main__': root = Tk() root.title("网络五子棋v2.0-服务器端") images = [PhotoImage(file='./images/BlackStone.png'), PhotoImage(file='./images/WhiteStone.png')] turn = 0 MyTurn = -1 maps = [[" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "] for y in range(15)] cv = Canvas(root, bg='green', width=610, height=610) drawQiPan() cv.bind("<Button-1>", callPos) cv.pack() label1 = Label(root, text="服务器端...") label1.pack() button1 = Button(root, text="退出游戏") button1.bind("<Button-1>", callExit) button1.pack() # 创建UDP SOCKET s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('localhost', 8000)) addr = ('localhost', 8000) startNewThread() root.mainloop()
-
建表,主键自增create table aaa( id bigint identity(1,1) not null PRIMARY key, name nvarchar(255) );navicat没办法给主键列,加identity,只能用sql建表赋值时,identity列不能赋值,报错一、identity的基本用法1.含义identity表示该字段的值会自动更新,不需要我们维护,通常情况下我们不可以直接给identity修饰的字符赋值,否则编译时会报错2.语法列名 数据类型 约束 identity(m,n)m表示的是初始值,n表示的是每次自动增加的值如果m和n的值都没有指定,默认为(1,1)要么同时指定m和n的值,要么m和n都不指定,不能只写其中一个值,不然会出错3.实例演示不指定m和n的值create table student1 ( sid int primary key identity, sname nchar(8) not null, ssex nchar(1) ) insert into student1(sname,ssex) values (‘张三',‘男'); insert into student1 values (‘李四',‘女');–可以省略列名 insert into student1 values (‘王五',‘女'); 指定m和n的值create table student2 ( sid int primary key identity(20,5), sname nchar(8) not null, ssex nchar(1) ) insert into student2(sname,ssex) values (‘张三',‘男'); insert into student2 values (‘李四',‘女');–可以省略列名 insert into student2 values (‘王五',‘女'); 4.删除一条记录接着插入把sid为2的记录删除,继续插入,新插入的记录的sid不是2,而是create table student3 ( sid int primary key identity, sname nchar(8) not null, ssex nchar(1) ) insert into student3(sname,ssex) values (‘张三',‘男'); insert into student3 values (‘李四',‘女'); delete from student3 where sid=2;–把sid为2的记录删除 insert into student3 values (‘王五',‘女');二、重新设置identity的值1.语法dbcc checkident(表名,reseed,n);n+1表示的是表中identity字段的初始值(n的值可以为0)也就是说:如果插入的是id为2的记录,则n的值是12.实例演示create table student4 ( sid int primary key identity, sname nchar(8) not null, ssex nchar(1) ) insert into student4(sname,ssex) values (‘张三',‘男'); insert into student4 values (‘李四',‘女'); delete from student4 where sid=2;–把sid为2的记录删除 dbcc checkident(‘student4',reseed,1);–把student4表中identity字段的初始值重新设置为1 insert into student4 values (‘王五',‘女');三、向identity字段插入数据1.语法set identity_insert 表名 on; insert into 表名(列名1,列名2,列名3,列名4) values (数据1,数据2,数据3,数据4); set identity_insert 表名 off;注意:插入数据时必须得指定identity修饰的字段的名字2.实例演示create table student5 ( sid int primary key identity(20,5), sname nchar(8) not null, ssex nchar(1) ) insert into student5(sname,ssex) values (‘张三',‘男'); insert into student5 values (‘李四',‘女'); insert into student5 values (‘王五',‘女'); set identity_insert student5 on; /* insert into student5 values (‘黑六',‘男');–error insert into student5 values (21,‘黑六',‘男');–error / insert into student5(sid,sname,ssex) values (21,‘黑六',‘男'); set identity_insert student5 off; / insert into student5 values (22,‘赵七',‘女');–error insert into student5(sid,sname,ssex) values (22,‘赵七',‘女');–error */ insert into student5 values (‘赵七',‘女');
-
【摘要】 使用Python连接GaussDB(DWS)的配置步骤及程序编写样例。配置方法:1、安装psycopg2;rpm -ivh python-psycopg2-2.5.1-3.el7.x86_64.rpm2、编写python脚本样例,并赋予执行权限;import psycopg2conn = psycopg2.connect(database="pocdb", user="u1",password="******", host="*.*.*.*", port="25308")cursor = conn.cursor()cursor.execute("DROP TABLE if exists test_conn")cursor.execute("CREATE TABLE test_conn(id int, name text)")cursor.execute("INSERT INTO test_conn values(1,'haha')")cursor.execute("INSERT INTO test_conn values(2,'lala')")cursor.execute("update test_conn set name = 'xixi'")cursor.execute("delete from test_conn where id = 1")conn.commit()cursor.execute("select * from test_conn")rows = cursor.fetchall()for row in rows: print 'id = ',row[0], 'name = ', row[1], '\n'cursor.close()conn.close()3、执行脚本刷新环境变量:source /opt/huawei/Bigdata/mppdb/.mppdbgs_profilepython test.py4、登录数据库,查验数据;步骤1 连接服务器:*.*.*.* root/*****,或者直接用omm用户连接,omm/******;步骤2 切换omm用户 ,刷新环境变量; source /opt/huawei/Bigdata/mppdb/.mppdbgs_profile步骤3 连接数据库; gsql -d pocdb -p 25308 -U u1 -W ****** -r 执行sql命令,\d+ tablename查看表定义; \d+ test_conn 查询表数据; Select * from test_conn;
-
不知不觉中,Python编程创造用第二阶段·Python进阶篇所有课程内容都已经全部更新完毕。大家积极的学习态度,遇到问题及时在学习群内提出,让本阶段课程可以顺利完成再次感谢大家:◎积极完成每章的随堂测验打卡,做到了课后的知识强化与巩固;◎认真完成每周读书笔记打卡,将自己的学习心得总结下来;◎有活力地问答官打卡,分享自己在学习中的问题和经验。十分感谢大家能顺利完成本阶段的学习内容,我们也在大家学习的过程中,总结了大家反馈的内容,对新阶段的课程会更好的输出和整合预告:Python编程创造营第三阶段将于4月16日开启,大家千万不要错过哦~现在,大家迎来了第二阶段考核,让我们来看一下考核的具体内容▶考核打卡时间:2021.04.12-2021.04.15 23:59 ▶考核途径:点击下方链接,选择【第二阶段考核】https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXX122+Self-paced/about▶考核要求:进入考核页面后,点击“【必读】考核要求”,详细阅读考核要求和评判标准后按要求进行考核,提交机会只有1次,请大家认真作答。▶打卡方式:如果您已经在云学院平台提交考核结果,后请您按照下列方式进行考核打卡只有在按照要求进行打卡才会得到本阶段考核证书!只有在按照要求进行打卡才会得到本阶段考核证书!只有在按照要求进行打卡才会得到本阶段考核证书!方式:打卡正确的回复格式:华为云账号+姓名(显示在考核证书上面名字)+提交完考核页面截图1张例如:华为云账号:grandmaster 姓名:华为云小助手05 考核截图如下重要提示:请严格按照回复示例进行回复,本次为阶段末考核项目,如果没有按照要求的格式进行回复,版主将不予提示,同时不计入考核结果,会影响考核证书及奖品的发放哦▶考核评分:本次考核满分100分,提交后直接显示成绩,成绩排行榜会在考核结束后10个工作日内公布,只有即参与考核又参与考核打卡的同学才会有分数和对应的奖励哦~分数会公布在博客里面,具体请大家留意小助手信息。▶考核奖励:◎参与最后考核并按要求回复本帖,就可得到电子版证书(证书上会根据大家的回复的真实姓名填写信息,请大家在留信息时注意)参与考核,人人有份,证书由05小助手微信点对点发放,没添加小助手企业微信的伙伴可以扫描下方二维码添加,证书将在第一阶段结束后15个工作日内发放,请大家耐心等待小助手的通知哦~(注意:凭各阶段电子证书最后可兑换实体证书哦~)◎参与考核即可获得20积分累计到总积分中,赢取最后积分大奖;◎考核分数≥60分并回复本帖,可得到考核积分额外的3积分!◎考核分数第1名将额外再获得10积分,第2名额外再获得7积分,第3名额外再获得5积分,当考核分数相同时,排名按照考核打卡帖时间进行排序(占楼无效!)◎特别提示:参加了移动应用开发所有阶段考核的同学们,最后可凭每阶段证书兑换整阶段实体证书一份,请大家关注后续规则!◎大家别忘了随堂测验,读书笔记和问答官排位赛回复打卡截止日期为04月15日23:59,抓紧时间打卡呀~积分排行榜奖品本次活动不仅免费跟大牛学习技术,更有积分大礼等着大家~每次有效提交的学习任务都会得到对应积分,累计积分最高者即可获得HUAWEI GT 手表,还有华为无线耳机、旅行套装、数十万码豆等着大家! 活动注意事项1.由于本帖回复内容为阶段考核测试内容,并涉及到个人隐私,已设置回帖仅版主可见,请大家放心回复2.请大家务必在考核规定时间04月15日 23:59内完成考核回帖打卡,否侧将影响证书和奖品的发放3.积分和考核奖品信息我们会在考核阶段结束后15个工作日内整理完毕4.华为云账号为实名认证,每个实名认证账号/或同一收货地址收货人只能获得一份奖品,请大家注意5.阶段结束后如遇预定奖品库存不足时,华为云会更换同等价位奖品给大家!
-
在常规python程序使用gsql交互数据时,每次都需要重新连接数据库,然后再执行查询SQL,特别是Select,查询结果还想继续和数据库交互时,利用以下方式实现。即使用expect实现该能力,代码参见如下,<gsql.py>#!/usr/bin/env python #coding:utf-8import pexpectimport sysimport osimport uuidimport timeimport re# similar psycopg2 to easy operate GaussDB(DWS) RDBMS.# require install ptyprocess,pexpectdef analyze_result(str): strList = str.replace("\n","").split('|') strListOut = [line.strip() for line in strList] return strListOutdef printL(str): print(time.strftime('[%Y-%m-%d %H:%M:%S]'),str) class con_gsql(): def __init__(self,host,port="25308",db="postgres",usr="omm",passwd="omm"): tmp = host.split(':') if len(tmpList) == 5: self,host,port,db,usr,passwd=tmp[0],tmp[1],tmp[2],tmp[3],tmp[4] self.RowCount = 0 self.Error = '' self.RowDict = {} self.debug = 0 self.cmd = '''gsql -h {host} -p {port} -d {db} -U {usr} -W {passwd} -L sql.log '''.format( host=host,port=port,db=db,usr=usr,passwd=passwd ) self.Db = db self.child = pexpect.spawn(self.cmd) self.index = self.child.expect([db+'=.',pexpect.EOF,pexpect.TIMEOUT]) if self.index != 0: printL("connect fail:"+re.sub('(\-W\s+)[^\s]+','{1} ***',self.cmd)) raise "connect fail" self.child.sendline('\\timing on') self.index = self.child.expect([db+'=.',pexpect.EOF,pexpect.TIMEOUT],timeout=5) if self.index != 0: printL("set timing fail:"+re.sub('(\-W\s+)[^\s]+','{1} ***',self.cmd)) raise "set timing fail" printL('connect %s successful'%host) def submit_sql(self,sql,TMOUT=600): printL(sql) if self.debug else None self.RowCount,self.Error,self.RowDict = 0,'',{} def_result,output = 0,'' if re.findall('^\s*select\s', sql, flags=re.IGNORECASE) \ or re.findall('^\s*\\[dsz]',sql) \ or re.findall('^\s*\\l+?\s*$',sql): def_result = 1 output = os.path.join(os.path.split( os.path.abspath(sys.argv[0]))[0], 'gsql_output_%s.log'%str(uuid.uuid1().hex)) self.child.sendline('\o %s' % output) self.child.expect([self.Db+'=.',pexpect.EOF,pexpect.TIMEOUT],timeout=TMOUT) if not re.findall('\;\s*$',sql): sql += ';' self.child.sendline(sql) self.child.expect([self.Db+'=.',pexpect.EOF,pexpect.TIMEOUT],timeout=TMOUT) sql_msg = self.child.before.decode('UTF-8') if 'ERROR:' in sql_msg: self.Error = re.findall('ERROR:\s(.*)',sql_msg)[-1] self.Error = 'known.' if not self.Error else None return self.Error if not def_result: return self.Error while not os.path.exists(output): time.sleep(0.2) fmtime = 0 while os.path.getmtime(output) != fmtime: fmtime = os.path.getmtime(output) time.sleep(1) with open(output,'r') as fh: all_rows = fh.readlines() try: os.remove(output) except: pass tmp = all_rows[2:-2] if not tmp: return self.Error self.RowCount = len(tmp) rows_list = [analyze_result(rowValue) for rowValue in tmp] for ind in range(len(rows_list)): self.RowDict[ind] = rows_list[ind] return self.Error def close(self,): self.child.sendline('\q')日常利用上面<gsql.py>当前数据库操作连接,实现SQL交互操作,实现具体业务逻辑。如希望进行一个schema下所有表执行一次analyze和count操作,import gsql con = gsql.con_gsql(host="xxx.xxx.xxx.xxx",port="xxx",db="xxx",usr="omm",passwd="omm")#also same method #con = gsql.con_gsql("xxx.xxx.xxx.xxx:xxx:xxx:omm:omm")sql = """select n.nspname,c.relname from pg_class c,pg_namespace n where c.relnamespace=n.oid and n.nspname='public' and c.relkind='r';""" rc = con.submit_sql(sql)if rc: print("sql error: %s"%rc) exit(1)print('output rows: %s'%con.RowCount)for i in con.RowDict: db,tb = con.RowDict[i][0],con.RowDict[i][1] sql = 'analyze %s.%s;'%(db,tb) rc = con.submit_sql(sql) if rc: print("sql error: %s"%rc) exit(1) sql = 'select count(*) from %s.%s;'%(db,tb) rc = con.submit_sql(sql) if rc: print("sql error: %s"%rc) exit(1) print('Table %s.%s rowcount: %s'% (db,tb,con.RowDict[i][0])con.close()有了该能力之后,相应多进程或多线程并发均可轻松实现;
-
解题思想:xlwt模块是非追加写.xls的模块,所以要借助for循环和列表,来一次性写入,这样就没有追加与非追加的说法。而合并Excel表,把每个Excel表当做行,即行合并,换一种想法,把Excel表中的标签当做列,可进行列合并,即合并不同文件中相同标签组成的不同标签,可以先合并不同文件中相同的标签,不同文件的相同标签组成一个列表,后合并前面组成的不同的标签,即可得到所有Excel文件的内容。源码如下:#导入xlrd和xlwt模块#xlrd模块是读取.xls的Excel文件的模块,xlwt模块是以非追加的方式写.xls的Excel文件的模块import xlrd,xlwt#导入要读的文件的路径a=["C:/Users/Desktop/m1.xls","C:/Users/Desktop/m2.xls"]#定义要写的文件的路径b="C:/Users/Desktop/m3.xls"#定义函数,判断打开文件是否会发生异常def open(fileaddress): try:#通过xlrd模块的open_workbook()方法,打开一个Excel文件,定义变量fo为文件句柄 fo=xlrd.open_workbook(fileaddress) return fo except Exception as e: print("error!"+str(e))#定义函数,得到某一个Excel文件下某一个标签的行数def getrows(fo,num): table=fo.sheets()[num]#sheets()函数为xlrd模块自带函数,能以列表的形式返回该Excel文件的标签 n=table.nrows#nrows为xlrd模块自带函数,通过某一个标签调用,可得到该标签的行数 return n"""定义函数,可通过Excel文件路径和标签的序列编号得到任意Excel文件任意标签的内容,且以列表的形式返回"""def getsheetcontents(fileaddress,num): avalue=[] fo=open(fileaddress) table=fo.sheets()[num] n=table.nrows for i in range(0,n): """ row_values()函数为xlrd模块自带函数,通过某一个标签调用, 可得到该标签的行数据,且这些行数据以列表形式返回,标签中 一列为一个列表的元素 """ rdate=table.row_values(i) avalue.append(rdate) return avaluesvalue=[]k=[]#通过for循环得到所有Excel文件的标签数,且以列表的形式返回for i in a: fo=open(i) k.append(len(fo.sheets()))#对这些标签数进行升序排序k.sort()#通过for循环把这些Excel文件中不同标签的所有内容放在列表svalue中for i in range(0,k[len(k)-1]):#通过for循环把不同Excel文件的同一个标签放在列表bvalue中 bvalue=[] for j in a: print("正在读取"+str(j)+"的第"+str(i)+"个标签") bvalue.append(getsheetcontents(j,i)) svalue.append(bvalue)#svalue里面就是所有Excel文件的内容#通过xlwt模块的Workbook()创建一个.xls文件,定义一个变量fw为文件句柄fw=xlwt.Workbook()line=0#add_sheet()函数为xlwt模块自带函数,可得到一个自定义标签#定义变量ws为标签句柄ws=fw.add_sheet("sheet1")"""通过for循环遍历svalue列表,把最终得到的某个标签某个文件某行某列的数据写入新标签中"""for i in range(0,len(svalue)): for j in range(0,len(svalue[i])): for m in range(0,len(svalue[i][j])): for n in range(0,len(svalue[i][j][m])): ws.write(line,n,svalue[i][j][m][n])#通过line
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签