首页 文章 精选 留言 我的

精选列表

搜索[Harness工程],共10000篇文章
优秀的个人博客,低调大师

写给前端工程师的10条实用原则

译者按: 牛人都说自己是站在巨人的肩膀上,我们也要善于学习他人的经验。 原文: 10 Things You Will Eventually Learn About JavaScript Projects 译者: Fundebug 为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。 小编推荐:Fundebug专注于JavaScript、微信小程序、微信小游戏,Node.js和Java线上bug实时监控。真的是一个很好用的bug监控服务,众多大佬公司都在使用。 JavaScript编程简直就是一项冒险。当回顾工业界这10年来经过不成熟到专业的开发历程,我想每个人都会认同这个观点。 js-adventure.jpeg 前端开发有很多丰富的选择性,充分的灵活性,以及大量发挥创造力的空间。不过,同时也要求我们自己需要有足够的知识,有一定的规划和自我约束。 一路走来,我们经历了jQuery,require.js,Angularjs,React,ExtJs等等。2018年的前端开发可以说是遍地开花。 在开发过程中,你会发现有一些通用的范式可以适用于各种复杂的项目。接下来我会介绍10个重要的范式,这些都是我多年来的个人经验。虽然都是个人的观点,我相信很多有经验的开发者都会认同。这一套规则适用于任何项目、任何框架、任何大小的团队。它可以减少开发者花在文档和重构的时间、甚至开发中的争吵。 1. 分而治之(Divide and conquer) divide-and-conquer.jpeg 这个词大家并不陌生,但是很多人低估了这条规则的适用场景和能力。CommonJS,Webpack,和Node都支持我们把代码拆分到多个文件,我们为什么还需要分而治之的理念? 一致性:当代码量越来越大,将项目拆分成一个个小的文件可以让查找和以来管理变得十分容易。并且文件命名要足够直观,反应了文件中代码做的相关工作。这样可以减少耗费脑力去查找代码结构的负担。 管理便捷:代码足够模块化的拆分使得文件的移动和进一步拆分变得简单。如果你发现一个帮助函数在应用中另一个地方也需要用到,你可以创建一个名为/shared的目录,将代码放进去。这样方便共用,也方便查找。 2. 任何东西都要超级直观易懂 ** 每一个变量、函数、文件名 -- 就如同给你的孩子取名字一样认真去给他们取名字。** bad_naming.png 也许你今天通过把它命名为x节省了0.3秒的时间,但是在接下来的一个月你将会花2天的时间来搞清楚x到底指代什么,然后再花4天做重构。好好想想,不要担心命名太长。 避免使用一些奇淫技巧(即使已经足以让你申请MIT) 你的方案也许很聪明但是负责,导致的后果就是在将来,你或则团队里面的其他成员将会浪费大量时间去理解你写的那段代码兜里是如何运作的。专注于用最直观简单的方法把事情搞定,甚至不需要文档或则评论 3. 不要使用魔法数字和字符串 magic_naming.jpg 和命名的原则一样,要直观易懂!不管你觉得可能多么简单的值,也要用一个有意义的变量名来声明。 在大多数情况下,任何你声明的值很有可能在其他地方复用。因此,通过声明变量的形式,可以减少代码重复,并且易于维护。 4. 避免嵌套太深 如果你写的代码一行超过120个字符,超过500行,或则if语句超过3层,最好做拆分。 nested-if.jpeg 你可以把嵌套的if语句拆分成函数,Promises,Observables。如果你使用了很多异步调用,使用async/await也可以极大简化你的代码。 5. 早点做好配置工作 如果你的应用中使用了全局变量,API接口,第三方认证等等,把它们放到单独的配置文件中去。 不管是网页(web)还是Node,都有很多可用的包(package)来管理配置,比如config。 某种程度上说,你的应用的配置应该做到可以支持运行在生产服务器和本地开发。早点创建配置文件比后面再来做要容易很多,特别是相应的环境配置,安全配置,功能配置等等。 6. 选用合适的框架 all-frameworks.png 花时间想清楚你是否需要框架,以及使用哪个框架。终端用户不会关心你的网站或者应用使用了一个在Github上超过10w stars的框架。 根据我的个人经验,我把它们简单的做了如下分类: React: 如果你需要对整体的架构和构建有充分的控制权,React是一个很好的选择。你需要花时间去熟悉React的整个生态系统,事先做好规划。而这些都是值得的,如果你很清楚你要什么。 Angular / VueJS / Ember: 如果你想要快速实现一个可靠的Web App,就选它们吧。虽然你可能对整个架构有一些不了解。这些框架帮你做了很多事情,所以在规划的时候要想清楚使用它的优点和缺点。它们严格的目录结构虽然少了自由,但是可以让你少犯错误。 jQuery / lodash / 或则类似的: 如果你想快速实现一个网页,并且没有多少的带宽可用,那么选用它们能节省你很多时间。不过你需要小心,因为你可能写出难以维护的代码。你要注意把它们当做辅助,而不是基础。 Vanilla / 不用框架: 如果你有很多的时间来计划和开发,那么使用纯JavaScript来写是个很好的选择。你可以做一些实验性的功能,比如引入WebGL,Workers,深度优化,或则动画等等。最终,你可能甚至做出了自己的一个框架。 把这些当做建议,你需要花时间慢慢去选择使用哪个框架最适合你的项目。 7. 除非是原型,否则一定要写测试 单元测试、冒烟测试、端到端测试、合理性(Sanity)检验。除非你的项目只是一个原型用来演示,否则赶紧写测试。当你的代码库越来越复杂后,将会变得难以维护和控制。这个时候,你需要测试来帮你做检查。 test.gif 在不远的将来,当你遇到bug的时候,你会仰望蓝天,谢天谢地的感慨好在当初写了测试。你永远无法预料新引入的功能是否会默默地把你之前的代码搞挂掉。 8. 使用版本控制 git.png 不管是一个原型、大型企业项目、或则是一个个人的小项目,使用git或则其它版本管理工具,从一开始就要管理起来。每天保持提交(commit),使用分支(branch),学会合并代码(merge),解决冲突,和回退到之前提交的版本。记得提交代码的消息要认真写,不能随意乱写。 版本控制可以让你更好地管理代码,如果今天这篇文章我介绍的其它点你都忘记了,这一点一定要记住。为什么呢?因为如果你没记住其它要点,这一点可以帮你很好的管理代码,辅助解决其它问题。 9. 状态管理 使用状态管理库,并且完全利用起来。 作为一个前端开发,我们往往只需要面对两个挑战- 展示数据和存储数据。而存储数据随着项目的复杂变得越来越难,因为你很容易忽略掉。 使用状态管理,很微妙。我们的应用往往需要在客户端和服务端保持一致。我们的目标是不要在中间加上复杂性,在我们使用JavaScript处理数据的时候。组件应该展示相同的数据、将用户的更新同步,对服务的的变动做出反馈。如何做到? React有着非常丰富的选择,对于Flux的架构使用Redux,Observable-based的架构则使用Mobx。每一种都有各自的优缺点,确保在使用前充分理解。 Angular, Ember, and VueJS 各自本身就是基于状态管理设计的,不过你还是可以使用额外的库,比如ngRx, Akita和Vuex。 对于其它的框架或则Vanilla JavaScript,你可以使用Redux、Mobx,或则你自己的状态管理方案。使用状态管理的目的是保证整个应用在全局层面数据保持一致。 10. 拥抱最新并质疑 最后,积极加入社区并从中学习 -- 不过要注意每一条评论、每一篇文章、每一个对你代码的反馈,你都要认真思考并适当质疑,而不是全盘接受。积极拥抱新的想法,前端的生态演化总是很快。但是,也不要仅仅为了追逐最新的事物而追,有些东西终究会被抛弃。 question.jpg ** 一个使用老一点、成熟的框架搭建的项目会更好、更稳定,胜过同时使用两个框架,仅仅因为另一个是新的。** 我们不得不承认新的框架可能会性能更好,不过我建议可维护性排在第一位,只有当你认为真的需要迁移的时候再做迁移。 关于Fundebug Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,得到了Google、360、金山软件等众多知名用户的认可。欢迎免费试用! 版权声明: 转载时请注明作者Fundebug以及本文地址:https://blog.fundebug.com/2018/08/27/code-interview-data-structure/ 屏幕快照 2018-08-29 上午8.29.58.png

优秀的个人博客,低调大师

Python全栈工程师(多继承、函数重写)

ParisGabriel 每天坚持手写一天一篇 决定坚持几年 为了梦想为了信仰 开局一张图 Python人工智能从入门到精通 补充: 对象 -------------------------> 类实例变量(属性) 类变量实例方法 类方法( @classmethond) 静态方法( @staticmethond)(类内普通函数) 继承/派生 单继承: 一个子类只有一个父类 一个父类可以有多个子类 -------------------------------------------------------------------------------------------- 用于类的函数: issublclass(cls, cls_or_tuple) 判断这个类是否继承自其他类, 如果此cls是class 或tuple中的一个派生子类, 返回True 否则返回False示例: class A: pass class B(A): pass class C(B): pass issublclass(C, B) # Trueissublclass(B, C) # Falseissublclass(C, (int, str)) # Falseissublclass(C, (int, B, str)) # True 封装 enclosure 封装是指隐藏类的实现细节,让使用者不关心这些细节 封装的目的是让使用者通过尽可能少的方法(或属性)操作对象私有属性和私有方法: python类中以双下划线(__)开头, 不以双下划线结尾的标识符为私有成员,私有成员或只能用类的方法进行访问和修改 以__开头的实例变量有私有属性 以__开头的方法有私有方法 示例: class A: def __init__(self): self.__p1 = 100 # 私有属性 def show_A(self): print("self.__p1", self.__p1) self.__m1() # 可以调用自己的方法 def __m1(self): # 私有方法 print("__m1(self)方法被调用") a = A() a.show_A() # 100 # print(a.__p1) # 出错 不能在类外部访问a.__p1私有属性 也不能在子类中访问 # a.__m1() # 出错 不能在类外部访问a.__p1私有方法 也不能在子类中访问 class B(A): pass b = B() print(b.__p1) # 出错,子类不能访问父类的私有成员 b.__m1() # 出错 b._A__p1 = 200 # python的假封装可以用此方法访问 print(b.__p1) # 200 多态polymorphic: 什么是多态 就是多种状态 多态是指在继承/派生关系的类中,调用基类对象的方法, 实际能够调用子类的覆盖方法的现象叫多态 状态: 静态(编译时状态)执行速度快 动态(运行时状态)执行速度慢说明: 多态调用方法与对象相关,不与类相关 Python的全部对象只有“运行时状态(动态)” 没有C++语言里的“编译时状态(静态)” 由于Python是解释执行的 是动态 没有静态 是在运行时编译(解释执行) 示例: # Pytgon中的运行时状态 class Shape: def draw(self): print("Shape的 draw 方法被调用") class Point(Shape): def draw(self): print("画车") class Circle(Shape): def draw(self): print("画圈") # python无法实现静态 除非不出现任何覆盖 def my_draw(s): # 其他静态语言 def my_draw(Circle s) 指定调用者 无法进行改变 s.draw() # 此处显示出"动态" s1 = Circle() s2 = Point() my_draw(s1) # 只有在调用时才能能确定调用哪一个 my_draw(s2) 面向对象不是编程而是一种思想面向对象的语言的特征: 继承 封装 多态 多继承:multiple inheritance 多继承是指一个子类继承自两个或两个以上的基类 语法: class 类名(基类名1, 基类名2, ...) 说明: 1.一个子类同时继承自多个父类,父类中的方法可以同时被继承下来 2.如果两个父类中同时有同名方法,而在子类中又没有覆盖此方法时, 调用结果难以确定 (也可以确定 C3算法)示例: class Car: def run(self, speed): print("汽车", speed, "Km/h 的速度行驶") class Plane: def fly(self, height): print("飞机以海拔", height, "米高度飞行") class PlaneCar(Plane, Car): '''同时继承Plane,Car的方法''' p1 = PlaneCar() p1.fly(10000) p1.run(300) 多继承的问题(缺陷): 标识符冲突的问题 要谨慎使用继承示例: # 多继承名字冲突问题 class A: def m(self): print("A.m被调用") class B: def m(self): print("B.m被调用") class AB(A, B): # 优先调用先出现的父类 有先后顺序 pass ab = AB() ab.m() # A.m被调用 class BA(B, A): pass ba = BA() ba.m() # B.m被调用 多继承的MRO(Method Resolution Order): 类的__mro__属性 __mro__ 是一个元组 里面存放类 此属性用来记录方法查找顺序示例: class A: def go(self): print("A") class B(A): def go(self): print("B") class C(A): def go(self): print("C") class D(B, C): def go(self): print("D") super().go() d = D() d.go() # B # 多继承的super调用关系一定是mro元组内的下一个类 和子父类没关系 # 如果没有方法则报错 调用算法(C3算法) # 正常调用也是mro顺序 函数重写: 在自定义类内添加相应的方法,让自定义类创建的实例 能像内建对象一样进行内建函数操作对象转字符串函数: repr(obj) 返回一个能代表此对象的表达式字符串,通常eval(repr(obj))== obj (这个字符串通常给Python解释执行器运行用的) str(obj) 返回的字符串(这个字符串通常给人阅读用的) 对象转字符串函数的重写方法: repr(obj) 函数的重写方法: def __repr__(self): pass str(obj) 函数的重写方法: def __str__(self): pass 说明: 1.str(obj)函数先查找, obj.str()方法 调用此方法并返回结果 2.如果没有obj.__str__方法时,返回obj.__repr__() 方法的结果并返回 3.如果obj.__repr__方法不存在,则调用obj类的__repr__ 实例方法显示:<__main__.XXXX object at 0x7f4b1c36fa90>示例: class MyNumber: def __init__(self, value): '构造函数,初始化MyNumber' self.data = value def __str__(self): '''转换为人能够识别的字符串''' print("__str__方法被调用") return "自定义数字类型对象:%d" % self.data def __repr__(self): '''转换为eval能够识别的字符串''' return 'MyNumber(%d)' % self.data n1 = MyNumber(100) n2 = MyNumber(200) print("repr(n1):--->", repr(n1)) print("strr(n2):--->", str(n2)) print("strr(n2):--->", n2.__str__()) 其他内建函数的重写方法:__abs__ abs(obj) 函数__len__ len(obj) 函数(必须返回整数)__reversed__ reversed(obj) 函数(必须返回可迭代对象)__round__ round(obj) 函数 示例: # 函数重写 class MyNumber: def __init__(self, v): self.data = v def __repr__(self): return 'MyNumber(%d)' % self.data def __abs__(self): '''__abs__函数重写 求绝对值函数''' # return -self.data v = abs(self.data) return MyNumber(v) # 创建一个新的MyNumber对象 def __len__(self): '''__len__函数重写 求长度函数''' # return len(self.data) i = 0 for x in self.data: i += 1 return i i1 = MyNumber(-10) print(i1) i2 = abs(i1) print(i2) i3 = MyNumber("123d5sa") print(len(i3)) 数据转换函数的重写:__complex__ complex(obj) 函数__int__ int(obj) 函数__float__ float(obj) 函数__bool__ bool(obj) 函数 示例: 数据转换构造函数重写 class MyNumber: def __init__(self, v): self.data = v def __repr__(self): return 'MyNumber(%d)' % self.data def __int__(self): # return 999999 # 可以自定义返回规则 return self.data n1 = MyNumber(100) x = int(n1) print(type(x)) # <class 'int'> print(bool(n1)) # True n2 = MyNumber(0) print(bool(n2)) # True # 默认返回 # True 布尔测试函数重写: 格式: __bool__ 作用: 用于bool(obj)函数取值 用于if语句的真值表达式中 说明: 1.当自定义的类内有__bool__(self) 方法时,此方法的返回值为bool(obj)的返回值 2.当不存在__bool__(self),bool(x) 返回__len__(self)方法的返回值是否为零来测试布尔值 3.当不存在__len__方法时,则直接返回True示例: # bool(x)函数重写 class MyList: '''自定义类型的列表,用来保存数据,内部用列表来储存数据''' def __init__(self, iterable): self.data = [x for x in iterable] def __repr__(self): return " MyList(%s)" % self.data def __len__(self): '''返回长度''' print("__bool__方法被调用") return len(self.data) # def __bool__(self): # print("__bool__方法被调用") # return False # 此处定义所有对象返回False def __bool__(self): print("__bool__方法被调用") for x in self.data: if not x: return False return True # 自定义返回规则(这就是函数重写) myl = MyList((1, 2, -3, 4, -5, 5)) print(myl) print(bool(myl)) if myl: print("myl是真值") else: print("myl是假值") 迭代器(高级): 什么是迭代器: 可以通过next(it)函数取值的对象就是迭代器 迭代器协议: 迭代器是指对象能够使用next函数获取下一项数据, 在没有下一项数据时触发一个StopIteration异常来终止迭代的重写 迭代器协议实现方法: __next__(self) 方法来实现迭代协议 语法形式: class MyIterator: def __next__(self): 迭代器协议 return 数据什么是可迭代对象: 是指用iter(obj) 函数返回迭代对象(实例) 可迭代对象内部需要定义__iter__(self)方法来返回迭代器对象 # 此示例示意让自定义的作为可迭代对象能让 for 语句迭代访问 class MyList: '''创建MyList类''' def __init__(self, iterable=()): '''初始化self iterable:可迭代对象 ''' # 用iterable生成列表 self.data = [x for x in iterable] def __repr__(self): '''返回一个MyList字符串''' return 'MyList(%s)' % self.data def __iter__(self): '''此方法必须返回一个迭代器对象 此方法创建一个迭代器对象并返回 ''' return MyListIterator(self.data) class MyListIterator: '''此类用来创建迭代器,此类型的迭代器可以迭代访问 MyList类型的对象''' def __init__(self, lst): self.data = lst self.cur_index = 0 # 初始化迭代器的起始位置 def __next__(self): '''此方法用于实现迭代器协议''' if self.cur_index >= len(self.data): # 如果索引越界就发终止迭代通知 raise StopIteration value = self.data[self.cur_index] # 要返回的值 self.cur_index += 1 return value myl = MyList([0, -1, 2, -3]) print(myl) # it = iter(myl) # print(next(it)) for x in myl: # 迭代访问自定义类型的可迭代对象 print(x) 练习: 写一个类Bicycle类 ,有 run方法.调用时显示骑行里程km class Bicycle: def run(self, km): print('自行车骑行了', km, '公里') 再写一个类EBicycle(电动自行车类), 在Bicycle类的基础上添加了电池电量 volume 属性, 有两个方法: 1. fill_charge(self, vol) 用来充电, vol为电量 2. run(self, km) 方法每骑行10km消耗电量1度,同时显示当前电量,当电量耗尽时调用 父类的run方法继续骑行 b = EBicycle(5) # 新买的电动有内有5度电 b.run(10) # 电动骑行了10km还剩 4 度电 b.run(100) #电动骑行了40km,还剩0度电,其余60用脚登骑行 b.fill_charge(10) # 又充了10度电 b.run(50) # 骑行了50公里剩5度电 答案: class Bycycle: def run(self, km): '''自行车''' print("自行车骑行了", km, "公里") class EBycyle(Bycycle): def __init__(self, volume=0): '''初始化电动车''' self.volume = volume print("新买的电动车有", volume, "度电") def fill_charge(self, vol): '''冲电''' self.volume += vol print("又冲了", vol, "度电") def run(self, km): self.volume -= (km / 10) # 减去使用的电量 x = abs(self.volume) * 10 # 计算超出的公里 if self.volume < 0: # 判断是否超出电量 self.volume = 0 print("电动车骑行了", km, "千米 还剩", self.volume, "度电 其余", x, "千米用脚蹬") else: print("电动车骑行了", km, "千米 还剩", self.volume, "度电") b = EBycyle(10) b.run(10) b.run(100) b.fill_charge(10) b.run(50) # 新买的电动车有 10 度电 # 电动车骑行了 10 千米 还剩 9.0 度电 # 电动车骑行了 100 千米 还剩 0 度电 其余 10.0 千米用脚蹬 # 又冲了 10 度电 # 电动车骑行了 50 千米 还剩 5.0 度电 b = EBycyle(50) b.run(10) b.run(100) b.fill_charge(10) b.run(50) # 新买的电动车有 50 度电 # 电动车骑行了 10 千米 还剩 49.0 度电 # 电动车骑行了 100 千米 还剩 39.0 度电 # 又冲了 10 度电 # 电动车骑行了 50 千米 还剩 44.0 度电 练习: 1. 修改原有的学生信息管理系统, 将学生对象的,全部属性 都变为私有属性,不让外部直接访问来实现封装 源码: https://pan.baidu.com/s/1szQDS5cfzVHLlZrrJcCs8A 2. 写一个列表类MyList实现存储整数列表,写类的定义如下: class MyList: def __init__(self, iterator): self.data = ... 让此类的对象能用for语句进行迭代访问 L = MyList(range(5)) print(L) L2 = [x ** 2 for x in L] print(L2) # [0, 1, 4, 9, 16] 答案: class MyList: def __init__(self, iterable=()): self.lst = [x for x in iterable] def __repr__(self): return "%s" % self.lst def __iter__(self): return MyIterable(self.lst) class MyIterable: def __init__(self, lst): self.lst = lst self.myindex = 0 def __next__(self): if self.myindex >= len(self.lst): raise StopIteration value = self.lst[self.myindex] self.myindex += 1 return value L = MyList(range(5)) print(L) for x in L: print(x) L2 = [x ** 2 for x in L] print(L2) 3. 写一个类Fibonacci 实现迭代器协议 ,此类的对象可以作为可迭代对象生成相应的斐波那契数 1 1 2 3 5 class Fibonacci: def __init__(self, n) # n代表数据的个数 ... ... 实现如下操作: for x in Fibonacci(10): print(x) # 1 1 3 5 8 .... L = [x for x in Fibonacii(50)] print(L) F = fibonicci(30) print(sum(F)) 答案: 直接继承第二题的类 class Fibonicci(MyList): def __init__(self, n): L = [1, 1] for _ in range(n - 2): L.append(L[-1] + L[-2]) self.lst = L for x in Fibonicci(10): print(x) # 1 1 3 5 8 .... L = [x for x in Fibonicci(50)] print(L) F = Fibonicci(30) print(F) print(sum(F))

优秀的个人博客,低调大师

Python全栈工程师(迭代器、字节串)

ParisGabriel 每天坚持手写一天一篇 决定坚持几年 为了梦想为了信仰 Python人工智能从入门到精通 迭代器 Iterator: 用<>括号表示的一定是对象 什么是迭代器? 迭代器是访问可迭代对象的工具 迭代器是指用iter(obj) 函数返回的对象(实例) 迭代器可以用next(it) 函数获取可迭代对象的数据 迭代器函数iter和next iter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象 next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIteration异常说明: 迭代器只能向前取值,不会后退 用iter函数可以返回一个可迭代对象的迭代器作用: 迭代器对象能用next函数获取下一个元素. 示例: L = [2, 3, 5, 7] it = iter(L) # 用L对象返回能访问L的迭代器, it绑定迭代器 next(it) # 2 next(it) # 3 next(it) # 5 next(it) # 7 next(it) # StopIteration 通知(没有数据) it = iter(range(1, 10, 30)) next(it) # 1 next(it) # 4 next(it) # 7 next(it) # StopIteration 用迭代器访问可迭代对象: L = [2, 3, 5, 7] for x in L: print(x) else: print('循环结束') it = iter(L) # 从L中获取一个迭代器 while True: try: x = next(it) print(x) except StopIteration: print("循环结束") break 生成器 Generator (python 2.5及之后)什么是生成器? 生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例) 动态就是现用现生成数据 生成器有两种: 1. 生成器函数 2. 生成器表达式 生成器函数的定义 含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象 yield 翻译为(产生或生成) yield 语句 语法: yield 表达式 说明: yield 用于 def 函数中,目的是将此函数作用生成器函数使用 yield 用来生成数据,供迭代器的next(it) 函数使用 yield 单步生成数据 在函数内可以一个或多少 实例: # 此示例示意用生成器函数生成一定范围内的自然数 def myinteger(n): i = 0 # 自然数从0开始 while i < n: yield i i += 1 for x in myinteger(3): print(x) 生成器函数说明: 生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象 在生成器函数调用return 会触发一个StopIteration异常生成器表达式: 语法: (表达式 for 变量 in 可迭代对象 [if 真值表达式 ]) 说明: if 子句可以省略 作用: 用推导式的形式创建一个新的生成器 示例: gen = (x ** 2 for x in range(1, 5)) it = iter(gen) next(it) # 1 next(it) # 4 next(it) # 9 next(it) # 16 next(it) # StopIteration迭代工具函数 迭代工具函数的作用是生成一个个性化的可迭代对象 函数:zip(iter1[, iter2[, ...]]) 返回一个zip对象,此对象用于生成元组,此元组的个数由最小的可迭代对象决定 enumerate(iterable[, start]) 生成带索引的枚举对象,返回迭代类型为索引-值对(index-value对),默认索引从零开始,也可以用start指定 示例: numbers = [10086, 10000, 10010, 9558] names = ['中国移动', '中国电信', '中国联通'] for t in zip(numbers, names): print(t) for x, y in zip(numbers, names): print(y, '的客服电话是:', x) x, y = (10086, '中国移动') # 序列赋值 zip函数的实现示例2: def myzip(iter1, iter2): it1 = iter(iter1) # 拿出一个迭代器 it2 = iter(iter2) while True: a = next(it1) b = next(it2) yield (a, b) for t in myzip(numbers, names): #能实现与zip同样的功能 print(t) enumerate 示例: names = ['中国移动', '中国电信', '中国联通'] for t in enumerate(names): print(t) enumerate 实现方法示意: def myenum(iterable): it = iter(iterable) i = 0 while True: a = next(it) yield (i, a) i += 1 字节串和字节数组 字节串bytes (也叫字节序列) 作用: 存储以字节为单位的数据 字节串是不可变的字节序列 字节: 字节是由8个位(bit)组成的数据单位,是计算机进行数据管理的单位 字节是用 0 ~ 255 范围内的整数表示的 创建空字节串的字面值 B = b'' B = b"" B = b'''''' B = b"""""" 创建非空字节串的字面值 B = b'ABCD' B = b"ABCD" B = b'\x41\x42' 字节串的构造函数 bytes bytes() 生成一个空的字节串 等同于 b'' bytes(整数可迭代对象) # 用可迭代对象初始化一个字节串 bytes(整数n) 生成n个值为0的字节串 bytes(字符串, encoding='utf-8') 用字符串转为编码生成一个字节串 示例: b = bytes() # b = b'' b = bytes(range(65, 69)) # b = b'ABCD' b = bytes(5) # b = b'\x00\x00\x00\x00\x00' b = bytes('abc中文') # b=b'ABC\xe4\xb8\xad\xe6\x96\x87' bytes 的运算: + += * *= < <= > >= == != in / not in 索引和切片 len(x) max(x) min(x) sum(x) any(x) all(x) bytes 和 str 的区别: bytes 存储字节( 通常值在 range(0, 256)) str 存储unicode字符( 通常值在0~65535) bytes 与 str 的转换 编码(encode) str ------------> bytes b = s.encode(encoding='utf-8') 解码(decode) bytes ----------> str s = b.decode(encoding='utf-8') 字节数组 bytearray可变的字节序列 字节数组的构造函数: bytearray bytearray() 创建空的字节数组 bytearray(整数) 用可迭代对象初始化一个字节数组 bytearray(整型可迭代对象) 生成n个值为0的字节数组 bytearray(字符串, encoding='utf-8') 用字符串的转换编码生成一个字节数组 bytearray 的运算: + += * *= < <= > >= == != in / not in 索引和切片 (字节数组支持索引和切片的赋值操作,规则同列表的索引和切片赋值规则) 例: ba = bytearray(b'aBCDEfG') ba[0] = 65 ba[-2] = 70 bytearray的方法: BA.clear() 清空 BA.append(n) 追加一个字节(n为0~255的整数) BA.remove(value) 删除第一个出现的字节,如果没有出现,则触发ValueError错误 BA.reverse() 字节顺序反转 BA.decode(encoding='utf-8') # 解码为字符串 BA.find(sub[, start[,end]]) # 查找 sub 练习: 有一个集合: s = {'唐僧', '悟空', '八戒', '沙僧'} 用 for语句来遍历所有元素如下: for x in s: print(x) else: print('遍历结束') 请将上面的for语句改写为 用while语句和迭代器实现 练习: 写一个生成器函数 myeven(start, stop) 此函数用来生成从 start开始到stop结束(不包含)区间内的一系列偶数 def myeven(start, stop): .... evens = list(myeven(10, 20)) print(evens) # [10, 12, 14, 16, 18] for x in myeven(21, 30): print(x) # 22, 24, 26, 28 L = [x**2 for x in myeven(3, 10)] print(L) # 16 36 64 练习: 已知有一个列表L L = [2, 3, 5, 7] 用生成器表达式从此列表中拿到数,生成 列表中数据的平方 gen = ...... # 此处用生成器表达式实现 L2 = list(gen) # L2 = [4, 9, 25, 49] 练习: 写一个程序,读入任意行的文字,当输入空行时结束输入 打印带有行号的输入结果: 如: 请输入: hello<回车> 请输入: world<回车> 请输入: tarena<回车> 请输入: <回车> # 直接回车结束输入 输出如下: 第1行: hello 第2行: world 第3行: tarena 练习: 写一个程序,从键盘输入一段字符串存入s变量 1. 将此字符串转为字节串用变量b绑定,并打印出b 2. 打印字符串s的长度和字节串b的长度 3. 将b字节串再转换为字符串用变量s2 绑定,判断 s2 和 s是否相同? s = input("please input string:") b = s.encode("utf-8") print(s) print(b) print(len(s)) print(len(b)) s2 = b.decode("utf-8") if s2 == s: print("相等") 练习: 1. 写一个生成器函数primes生成素数, 此生成器函数为 primes(begin, end) 如: [x for x in primes(10, 20)] 将得到列表 [11, 13, 17, 19] 答案: def get_ss(x): if x <= 0: return False for i in range(2, x): if x % i == 0: return False return True def primes(begin, end): if begin <= 2or end <= 2: pass for x in range(begin, end): if get_ss(x): yield x L = [x for x in primes(10, 20)] print(L) 2. 写一个生成器函数,生成斐波那契数列的前n个数 1 1 2 3 5 8 13 def fibonacci(n): ... yield... 1) 输出前20个数: for x in fibonacci(20): print(x) 2) 打印前40个数的和: print(sum(fibonacci(40))) 答案: def fibonacci(n): L = [1, 1] for x in range(n): s = L[x] + L[x + 1] L.append(s) return L print(fibonacci(20)) print(sum(fibonacci(40))) 3. 写 程序打印杨辉三角(只打印6层) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 答案: def yh_sj(): L = [1] while True: yield L L.append(0) L = [L[x - 1] + L[x] for x in range(len(L))] def lst(): i = 0 for x in yh_sj(): print(str(x).center(50)) if i == 10: break i += 1 思考: L = [2, 3, 5, 7] L2 = [x ** 2 for x in L] # 列表推导式 it = iter(L2) print(next(it)) # 4 L[1] = 10 print(next(it)) # 9 L = [2, 3, 5, 7] G3 = (x ** 2 for x in L) # 生成器表达式 it = iter(G3) print(next(it)) # 4 L[1] = 10 print(next(it)) # 100 生成器是动态的现用现去 跟着数据变化所变化

优秀的个人博客,低调大师

Python全栈工程师(包、模块 的导入)

ParisGabriel 每天坚持手写一天一篇 决定坚持几年 为了梦想 为了信仰 Python人工智能从入门到精通 $ pip3 install tensorflow: 第三方模块 tensorflow 的安装 电脑必须有网 命令行自动下载安装dir(模块名): 查看模块所有属性 自定义模块导入 示例: 自定义模块的实现方法 def myfac(n): print('正在计算', n, '的阶乘') def mysum(n): print("正在计算1+2+3+...+%d的和" % n) name1 = "Audi" name2 = "TESLA" print("mymod模块被加载!") 注意事项: 自定义模块的文件要求以.py结尾,文件名必须是标识符的规则 导入 语句 import 语句等 搜索块的路径顺序 import mymod from mymod import myfac from mymod import * 去哪儿找这个mymod.py? 搜索顺序: 1. 搜索程序运行时的路径(当前路径) 2. sys.path 提供的路径 sys.path是一个列表,里面放的都是模块的搜索路径 3. 搜索内建模块模块的加载过程: 1. 在模块导入时,模块的所有语句都会执行 2. 如果一个模块已经导入,则再次导入时不会重新执行模块内的语句 模块的重新加载 import mymod import imp imp.reload(mymod) # 重新加载mymod模块 模块以导入和执行的过程: 1. 先搜索相关的路径,找到模块名.py 2. 判断是否有此模块对应的.pyc文件。如果.pyc比.py文件新,则直接加载.pyc文件 3. 否则 用模块.py,文件生成.pyc,并加载执行 pyc python的编译 编译 解释执行 mymod.py --------> mymod.pyc --------> python3 模块--------> 编译好的Python3文件--------> Python3解释执行器 模块的文档字符串: 模块内第一个没有赋值给任何变量的字符串称为模块的文档字符串 模块的 __doc__ 属性 此属性用于绑定模块的文档字符串 模块的 __file__属性 此属性用于记录模块对应的文件路径名 示例: # 模块的文档字符串:'''我的自定义模块mymod2此模块有两个函数 myfac和 mysum...''' def myfac(n): '''自定义用来测试用的myfac的文档字符串''' print('正在计算', n, '的阶乘') def mysum(n): print("正在计算1+2+3+...+%d的和" % n) name1 = "Audi" name2 = "TESLA" print("mymod模块被加载!") 模块的 __name__属性 __name__属性 用来记录模块自身名字 作用: 1. 记录模块名 2. 用来判断是否为主模块 说明: 当此模块为主模块(也就是第一个运行的模块时)运行时, __name__绑定 '__main__' 当此模块不是主模块时,而是被其它模块导入时,此时 __name__ 绑定模块名 示例: '''此示例示意 mymod3的 __name__属性的用法''' def test(): pass print("__name__属性绑定的值是:", __name__) if __name__ == '__main__': print("当前mymod3.py 正在以主模块运行") else: print("当前mymod3.py 正在被其它模块导入") print("我的模块名是", __name__) 模块的 __all__列表 模块中的 __all__列表是一个用来存放可导出属性的字符串列表 作用: 当用 from xxx import *语句导入时,只导入 __all__ 列表内的属性 并且只对 from xx import * 有效 示例: # __all__属性只对 from import * 语句有效 __all__ = ['hello1', 'name1'] def hello1(): pass def hello2(): pass def hello3(): pass name1 = 'aaaaaa' name2 = 'aaaaaa' 模块的隐藏属性 模块中以'_'开头的属性,在from xxx import * 导入时,将不被导入,通常称这些属性为隐藏属性 示例: 此模块在用from mymod5 import *导入时,只能导入: # f1和 name1 def f1(): pass def _f2(): pass def __f3(): pass name1 = 'aaaaa' _name2 = 'bbbbb' 随机模块 random 模块名: random 作用: 用于模拟或生成随机输出的模块 随机模块 random 说明: random模块是用于模拟或生成随机输出的模块. import random as R 函数名 描述 R.random() 返回一个[0, 1) 之间的随机实数 R.uniform(a,b) 返回[a,b) 区间内的随机实数 R.randrange([start,] stop[, step]) 返回range(start,stop,step)中的随机数 R.choice(seq) 从序列中返回随意元素 R.shuffle(seq[, random]) 随机指定序列的顺序(乱序序列) R.sample(seq,n) 从序列中选择n个随机且不重复的元素 系统模块 sys 运行时系统相关的信息 sys模块的属性 属性 描述 sys.path 模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 '' sys.modules 已加载模块的字典 sys.version 版本信息字符串 sys.version_info 版本信息的命名元组 sys.platform 操作系统平台名称信息 sys.argv 命令行参数 argv[0] 代表当前脚本程序路径名 sys.copyright 获得Python版权相关的信息 sys.builtin_module_names 获得Python内建模块的名称(字符串元组) sys模块的函数 函数名 描述 sys.exit([arg]) 退出程序,正常退出时sys.exit(0) sys.getrecursionlimit() 得到递归嵌套层次限制(栈的深度) sys.setrecursionlimit(n) 得到和修改递归嵌套层次限制(栈的深度) 包(模块包) package 包的定义 包是将模块以文件夹的组织形式进行分组管理的管理方法 作用: 将一系列模块进行分类管理,有利于防止命名冲突 可以在需要时加载一个或部分模块则不是全部模块包目录树示例: mypack/ (包名) __init__.py (__init__.py 文件) menu.py (模块) games/ (子包名1) __init__.py (__init__.py 文件) contra.py (模块) supermario.py (模块) tanks.py (模块) office/ (子包名2) __init__.py (__init__.py 文件) word.py (模块) excel.py (模块) powerpoint.py (模块) __init__.py 文件 __init__.py是常规包内必须存在的文件 __init__.py会在包加载时自动调用 作用: 1. 编写此包的内容 2. 在内部填写文档字符串 3. 在__init__.py文件内可以加载此包所依懒的一些其它模块 包的导入 同模块的导入规则 # import 语句 import 包名 [as 包新名] import 包名.模块名 [as 模块新名] import 包名.子包名.模块名 [as 模块新名] # from import语句 from 包名 import 模块名 [as 模块新名] from 包名.子包名 import 模块名 [as 模块新名] from 包名.子包名.模块名 import 属性名 [as 属性新名] # from import *语句 from 包名 import * from 包名.模块名 import * ... 导入包时的索引路径顺序: 1. 搜索程序的当前路径 2. sys.path 提供的路径 __init__.py内的 __all__ 列表 作用: 用来记录此包中有哪儿些子包或模块在用from import *语句 时被导入 说明: __all__列表只对 from xxx import *语句起作用 包的相对导入: 包的相对导入是指包内模块的相互导入(不能超过包的最高界限) 语法: from 相对路径包或模块 import 属性或模块名 from 相对路径包或模块 import * 相对路径 . 代表当前目录 .. 代表上一级目录 ... 代表上二级目录 .... 以此类推 注: 相对导入时不能超出包的外部 模块的导入分三种 import tiem 直接导入模块 from time import time 导入time模块的time功能 from mymod import * 导入time模块的所有功能 这里*导入可以直接使用函数不需要加模块名.函数 如果有__all__属性只导入__all__列表里的 包也是分三种 差不多 包所导入的是文件夹 as 给包或者模块、属性、等 改名 (.)统一代表什么什么下的什么什么 解释执行器就是先把.py文件翻译成二进制码.pyc文件再进行运行(先解释后执行) 但运模块时自动创建__pycache__ 文件夹 里面放.pyc文件 文档字符串和函数一样 一般用三引号括起来 写就可以了 第一行是标题 换行 第三行开始写详细内容 __name__属性返回一个字符串 如果返回 __main__代表程序主入口 也就是第一个运行的模块 否则返回当前模块的名字 __all__ 属性是一个列表 当三种导入方式导入时只导入列表里的其他的不导入__开头的函数 属性 当三种导入方式导入时不导入_开头的隐藏函数 其他的全导入__init__.py 是必须存在的文件 不存在 此文件夹就不是包 里面可以写属性 包的文档字符串 导入路径 优先相对路径 其次sys.path路径 相对路径 就是 当前路径 或 路径名加上模块 path是系统环境变量列表 相当于全局变量 在任何目录都能调用这个列表里的路径 练习: 1. 猜数字游戏 随机生成一个 0~100之间的一个整数,用变量x绑定 让用户输入一个数y,输出猜数字的结果: 1) 如果y大于x则提示: "您猜大了" 2) 如果y小于x则提示: "您猜小了" 3) 如果y等于生成的数x,则提供示用户"恭喜您猜对了 "并退出猜数字 循环重复上述步聚,直到猜对为止。 猜对了,显示用户猜数字的次数,然后退出程序 答案: import random x = random.randrange(101) i = 0 while True: s = int(input("请输入要猜的数字0~100:")) i += 1 if s > x: print("大了") elif s < x: print("小了") else: print("猜对了") print("猜了%d次" % i) break 这里有个2分算法 100内的猜数字一般不超过7次猜对 10000不超过20次就能猜对 练习: 1. 写一个闹钟程序,启动时设置定时时间, 到时间后打印一句"时间到...." 然后退出程序 import time def time_out(): h = int(input("please input:")) m = int(input("please input:")) s = int(input("please input:")) d = (h, m, s) while True: s = time.localtime() print('%02d:%02d:%02d' % (s[3], s[4], s[5]), end = "\r") time.gmtime(1) if s[3: 6] >= d: print("Time out") break time_out() 2. 模拟斗地主发牌,扑克牌共54张 黑桃('\u2660'), 梅花('\u2663'), 方块('\u2665'), 红桃('\u2666') A2-10JQK 大王、小王 三个人玩,每人发17张牌,底牌留三张 输入回车, 打印出第1个人的17张牌 输入回车, 打印出第2个人的17张牌 输入回车, 打印出第3个人的17张牌 输入回车, 打印三张底牌 答案: import random L = {"大王", "小王"} range(2, 11) for x in {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}: L.add("\u2660 " + x) L.add("\u2663 " + x) L.add("\u2665 " + x) L.add("\u2666 " + x) print("共54张牌:", L) print() for x in range(3): input() s = set(random.sample(L, 17)) if x == 0: x = "第一个玩家:" elif x == 1: x = "第二玩家:" elif x == 2: x = "第三个玩家:" print(x, s) L -= s print() print("底牌:", L) 今天的: 3. 修改学生信息管理程序,将原student_info.py 拆分为模块 要求: 1. 主事件循环放在main.py中 2. show_menu 函数放在menu.py中 3. 与学生操作相关的函数放在 student_info.py中 还有昨天的: 3. 改写之前的学生信息管理程序 要求添加四个功能: | 5) 按学生成绩高-低显示学生信息 | | 6) 按学生成绩低-高显示学生信息 | | 7) 按学生年龄高-低显示学生信息 | | 8) 按学生年龄低-高显示学生信息 | 下载地址:https://pan.baidu.com/s/17xFe_r0g8a-nP1PrUoTXCA 已 吐血身亡 下次补上 太晚了 嘤嘤嘤......... # 创建输入函数:input_student开始 封装信息输入 # 创建输出函数:student完成 临时菜单封装 def student(): for a in range(1, 8, 2): x = "*" * a print(x.center(9), x.center(10), x.center(10), x.center(9)) else: for y in range(1, 4 + 1): c = "*" if 4 >= 10: c = "***" print(c.center(9), c.center(10), c.center(10), c.center(9)) print("^^^^^^^^^^^^^ System menu ^^^^^^^^^^^^^") print("---------------------------------------") print(" 1): Add Student information ") print("---------------------------------------") print(" 2): print Student information ") print("---------------------------------------") print(" 3): delete Student information ") print("---------------------------------------") print(" 4): revamp Student information ") print("---------------------------------------") print(" 5): Results sorting High --> low") print("---------------------------------------") print(" 6): Results sorting low --> High") print("---------------------------------------") print(" 7): Age sort High --> low ") print("---------------------------------------") print(" 8): Age sort low --> High ") print("---------------------------------------") print(" please input number 1~8 select ") print("---------------------------------------") print(" input :(Q)Exit procedure ") print("---------------------------------------") # 创建输出函数:perform完成 def input_student(): L = [] print("--------Student information enty--------") while True: name = input("please input name:") if name == "": q = input("operation succeed! return y / n :") if q == "y": break else: input_student() age = int(input("please input age:")) score = int(input("please input score:")) d = {} d = {"name": name, "age": age, "score": score} print("+---------------+----------+----------+") name = d["name"].center(15) age = str(d["age"]).center(10) score = str(d["score"]).center(10) print('''|%s|%s|%s|''' % (name, age, score)) print("+---------------+----------+----------+") print("-----Not input Enter be no revamp!-----") L.append(d) return L # 创建输入函数:input_student完成 # 创建输出函数:output_student开始 封装列表打印 def output_student(lst): print("-------Student information sheet-------") print("+---------------+----------+----------+") print("| Name | Age | Score |") print("+---------------+----------+----------+") for x in lst: name = x["name"].center(15) age = str(x["age"]).center(10) score = str(x["score"]).center(10) print('''|%s|%s|%s|''' % (name, age, score)) print("+---------------+----------+----------+") q = input("operation succeed! return y / n :") if q == "y": pass else: output_student() # 创建输出函数:output_student完成 # 创建输出函数:delete_student开始 封装删除信息 def delete_student(lst): name = input("please input name delete:") for x in lst: if x["name"] == name: print("+---------------+----------+----------+") name = x["name"].center(15) age = str(x["age"]).center(10) score = str(x["score"]).center(10) print('''|%s|%s|%s|''' % (name, age, score)) print("+---------------+----------+----------+") delet = input("whether delete (y:yes/y:no):") if delet == "y": lst.remove(x) q = input("operation succeed! return y / n :") if q == "y": pass else: delete_student() # 创建输出函数:delete_student完成 # 创建输出函数:revamp_student()开始 封装更改信息 def revamp_student(lst): name = input("please input name revamp:") for x in lst: if x["name"] == name: print("+---------------+----------+----------+") name = x["name"].center(15) age = str(x["age"]).center(10) score = str(x["score"]).center(10) print('''|%s|%s|%s|''' % (name, age, score)) print("+---------------+----------+----------+") print("-----not input Enter be no revamp!-----") rage = input("please input age revamp:") rscore = input("please input score revamp:") if rage != "": x["age"] = rage if rscore != "": x["score"] = rscore print("+---------------+----------+----------+") name = x["name"].center(15) age = str(x["age"]).center(10) score = str(x["score"]).center(10) print('''|%s|%s|%s|''' % (name, age, score)) print("+---------------+----------+----------+") print("-----------revamp perform!------------") q = input("operation succeed! return y / n :") if q == "y": pass else: revamp_student() # 创建输出函数:revamp_student()完成 # 创建输出函数:output_student_by_score_desc开始 成绩高~低排序 def output_student_by_score_desc(lst): def k(d): return int(d['score']) L = sorted(lst, key=k, reverse=True) output_student(L) # 创建输出函数:output_student_by_score_asc开始 成绩低~高排序 def output_student_by_score_asc(lst): L = sorted(lst, key=lambda d: int(d['score'])) output_student(L) # 创建输出函数:output_student_by_age_desc开始 年龄高~低排序 def output_student_by_age_desc(lst): L = sorted(lst, key=lambda d: int(d['age']), reverse=True) output_student(L) # 创建输出函数:output_student_by_age_asc开始 年龄低~高排序 def output_student_by_age_asc(lst): L = sorted(lst, key=lambda d: int(d['age'])) output_student(L) # 创建输出函数:System_menu()开始 临时封装系统 def System_menu(): L = [] while True: student() select = input(" please input:") if select == '1': L += input_student() elif select == '2': output_student(L) elif select == '3': delete_student(L) elif select == '4': revamp_student(L) elif select == '5': output_student_by_score_desc(L) elif select == '6': output_student_by_score_asc(L) elif select == '7': output_student_by_age_desc(L) elif select == '8': output_student_by_age_asc(L) elif select == 'q': break # 创建输出函数:System_menu()完成 临时封装系统 # 运行

优秀的个人博客,低调大师

Python全栈工程师(函数的传参)

ParisGabriel 感谢 大家的支持 每天坚持 一天一篇 点个订阅吧灰常感谢 当个死粉也阔以 Python人工智能从入门到精通 “\n”Linux 换行符"\r\n" Windows换行符 函数的参数传递: 传参方式:(2种) 位置传参(包含关系 ) 序列传参 关键字传参(包含关系) 字典关键字传参位置传参: 实际参数(实参)的对应关系与形式参数(形参) 的对应关系是安位置来依次对应的 说明: 实参和形参通过位置进行传递和匹配 实参的个数必须与形参的个数相同序列传参: 序列传参是指在函数调用过程中,用 * 将序列拆解 后按照位置进行传递的方式 说明: 序列传参时,序列拆解的位置与形参一一对应 序列的位置信息对应相应的形参的位置关键字传参: 关键字传参是指传参时,按着形参的名称给形参赋值、实参和形参按形参名进行匹配 字典关键字传参: 是指字典,将字典用“**”拆解后再进行关键字传参的方式 说明: 字典的键名必须和形参名一致 字典的键名必须是字符串且标识符 字典额键名要在形参中存在综合传参: 函数的传参方式在能确定形参能唯一匹配到相应实参的情况下可以任意组合 说明: 位置传参(序列传参)一定要在关键字传参(字典关键字传参)的左侧 示例: def fu(a, b, c): print("a=", a) print("b=", b) print("c=", c) fu(100, *[200, 300]) fu(*[100, 200], 300) fu(100, 200, 300) fu(100, b=200, c=300) fu(100, **{"c": 200, "b": 300}) --------------------函数的形参定义--------------------函数的缺省参数: 语法: def 函数名 (形参名1=默认实参1, 形参2=默认实参2) 语句块 说明: 缺省参数必须从右至左依次存在的,如果一个参数有缺省参数, 则右侧的所有参数都必须有缺省参数函数的形参定义: 1.位置形参 2.星号元组形参 3.命名关键字形参 4.双星号字典形参 位置形参: 语法: def 函数名(形参1, 形参2.......) 语句块 元组形参: 语法: def 函数名(*元组形参名): 语句块 作用: 收集多余的位置传参 命名关键字形参: 语法: def 函数名(*, 命名关键字形参): 语句块 或 def 函数名(*args, 命名关键字形参): 语句块 (关键字形参 必须用关键字传参) 作用: 强制所有的参数都参数都必须用关键字传参或字典关键字传参双星号字典传参: 语法: def 函数名(**字典形参名): 语句块 作用: 收集多余关键字传参 字典形参名通常命名为:kwargs函数的参数说明: 位置形参、星号元组形参、命名关键字形参、双星号字典形参可以混合使用函数自左到右的顺序为: 1.位置形参 2.星号元组形参 3.命名关键字形参 4.双星号字典形参 例如: def fx(a, b, *args, c, **kwargs): pass fx(100, 200, 300, 400, c="c", d="d")函数的不定长参数: 星号元组形参,双星号字典形参 说明: 可以接收任意位置传参和关键字传参 例如: def fn(*args, **kwargs) pass全局变量和局部变量: 局部变量:local variable 1.定义函数内的变量成为局部变量(函数的形参也是局部变量) 2.局部变量只能在函数内部使用 3.局部变量在函数调用时才能够被创建,在函数调用之后被销毁 全局变量:global variable 定义在函数外,模块内的变量称为全局变量 全局变量所有函数都可以直接访问(但函数内不能将其直接赋值) 练习: 1.写一个函数minmax(a, b, c) 有三个参数,这回这三个参数中的最小值和最大值, 要求,形成元组,最小值在前,最大值在后,如: def minmax(a, b, c): ... t = minmax(11, 33, 22) print(t) # (11, 33) # <<< 打印元组 xiao, da = minmax(6, 5, 4) print('最小值:', xiao, '最大值:', da) 答案: def minmax(a, b, c): x = a if x > b: x = b if x > c: x = c z = a if z < b: z = b if z < c: z = c L = [x, z] print(L) minmax(2, 1, 3)方法二: def minmax(a, b, c): L = [min(a, b, c), max(a, b, c)] print(L) minmax(2, 3, 1) 其实方法二 这样也是可以的不过就是有点不厚道了 这不属于二道贩子嘛 2.写一个函数 myadd, 此函数可以计算两个数的和,也可以计算三个数的和 def myadd(......): .... print(myadd(10, 20)) # 30 print(myadd(100, 200, 300)) # 600 答案: def myadd(a, b, c=0): return a + b + c print(myadd(100, 200, 300)) print(myadd(100, 200)) def mysum(*args): return sum(args) 皮一下很开心 mysum = sum 3 . 写一个函数,print_odd, 此函数可以传递一个实参,也可以传递两个实参,当传递一个实参时代表结束值 当传递两个实参时,第一个实参代表起始值,第二个实参代表结束值 打印出以此区间内的全部奇数,不包含结束数: print_odd(10) # 1 3 5 7 9 print_odd(11, 20) # 11 13 15 17 19 答案: def print_odd(a, b=None): if b == None: b = a a = 0 for x in range(a, b): if x % 2 != 0: print(x, end=" ") print_odd(10)# 1 3 5 7 9 print_odd(11, 20)# 11 13 15 17 19 4. 写一个函数, mysum可以传入任意个实参的数字,返回所有实参的和 def mysum(*args): ... print(mysum(1, 2, 3, 4)) # 10 print(mysum(10, 20, 30)) # 60 答案: def mysum(*args): i = 0 for x in args: i += x return i print(mysum(1, 2, 3, 4)) # 10 print(mysum(10, 20, 30)) # 60 6. 创建一个全局变量 L = [] 写一个函数: def input_number(): .... 此函数每次调用将从键盘读入一些数字追加到列表L中 如: L = [] def input_number(): .... input_number() print(L) # [ .... 这些是您从键盘输入的数..] L = [] def input_number(): while True: a = int(input("please input (-1 over):")) if a < 0: break L.append(a) return L L = input_number() print(L) # [ .... 这些是您从键盘输入的数..] 7. 写一个函数isprime(x) 判断x是否为素数。如果是素数,返回True,否则返回False 答案: def isprime(x): if x > 2: for i in range(2, x): if x % i == 0: s = False break else: s = True else: if 1 < x < 3: s = True else: s = False return s x = isprime(4) print(x) 8. 写一个函数prime_m2n(m, n) 返回从m开始,到n结束(不包含n)范围内的素数,返回这些素数的列表并打印 如: L = prime_m2n(5, 10) print(L) [5, 7] 答案: def prime_m2n(m, n): L = [] for x in range(m, n): if isprime(x) == True: L.append(x) return L L = prime_m2n(5, 10) print(L) 9. 写一个函数pimes(n) 返回小于n的全部素数的列表,并打印这些素数 如: L = primes(10) print(L) # [2, 3, 5, 7] 1) 打印100 以内的全部素数 2) 打印200 以内的全部素数的和 答案: def pinmes(n): return prime_m2n(1, n) L = pinmes(10) print(L) # [2, 3, 5, 7] print(pinmes(100)) print(sum(pinmes(200))) 10. 编写函数 fn(n) 此函数返回下列级数的和: fn(n) = 1/(1*2) + 1/(2*3) + .... + 1/(n*(n-1)) 的和 print(fn(100)) 答案: def fn(n): s = 0 for i in range(1, n): s += 1 / (i * (i + 1)) return s print(fn(100)) 一波经验加成buff: (咳咳 C波牛B) 开局 一人 一电脑 ,一键盘999999999999999级你肯会迷茫 晕眩 摸不着头尾 没关系 给你加个经验值BUFF 因为很多专业术语比较抽象 再加上翻译差别 所以说很多人都是知道专业术语该怎么说叫什么 一般容易记住和记忆最久的应该就是用自己的方式去跟现实或者一些列子对比越白话文越好记 什么花里胡哨的术语 知道是什么就行了 (能记还是要记得 说也尽量说 只是在你脑子里是一个对应的实例关系 就好比 变量 在内存中.......跑题了 溜了 溜了) 实参、传参、形参是什么 ? 实参就是调用函数时的参数 传参就是把形参传给实参的过程 形参就是定义(封装)函数时的参数字典关键字传参就是把字典先用(**)拆开分成形参和实参 键代表关键字(形参、不可变) 值代表参数(实参、可变) 一个键对应一个值 一个关键字对应一个参数 列表、元组 都是属于顺序传参 先用(*)拆分后传参 关键字传参必须有关键字(形参)和参数(实参)传参的排序规则: 从左到右 1.位置形参 2.星号元组形参 3.命名关键字形参 4.双星号字典形参 变量没什么可说的 就相当于一个公共电话(全局)和私人手机(局部) 所有人都可以用公共电话 你的私人手机你会让所有人用吗?我想不会吧

优秀的个人博客,低调大师

Web前端工程师常用的8个工具

1、HBuilder 功能简介: HBuilder是专为前端打造的开发工具,具有飞一样的编码、最全的语法库和浏览器兼容数据、可以方便的制作手机APP、最保护眼睛的绿柔设计等特点。支持HTML、CSS、JS、PHP的快速开发。从开放注册以来深受广大前端朋友们的喜爱。 2、Sublime Text 功能简介: Sublime Text是一个代码编辑器也是HTML和散文先进的文本编辑器。漂亮的用户界面和非凡的功能,例如迷你地图,多选择,Python的插件,代码段,等等。完全可自定义键绑定,菜单和工具栏。Sublime Text的主要功能包括:拼写检查,书签,完整的Python API,Goto功能,即时项目切换,多选择,多窗口等等。 3、PS 功能介绍: Dobe Photoshop,简称“PS”,是由AdobeSystems开发和发行的图像处理软件。 Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。ps有很多功能,在图像、图形、文字、视频、出版等各方面都有涉及。 4、Dreamweaver 功能介绍: dreamweaver是个由Macromedia公司所开发的著名网站开发工具。它使用所见即所得的接口,亦有HTML编辑的功能。 5、WebStorm 功能介绍: WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。 6、Visual Studio Code 功能介绍: Visual Studio Code中文版是微软推出的带 GUI 的代码编辑器,软件功能非常强大,界面简洁明晰、操作方便快捷,设计得很人性化。软件主要改进了文档视图,完善了对 Markdown的支持,新增PHP语法高亮。 7、wampServer 功能介绍: WampServer,是Windos Apache Mysql PHP集成安装环境,即在window下的apache、php和mysql的服务器软件。PHP扩展、Apache模块,开启/关闭鼠标点点就搞定,再也不用亲自去修改配置文件了,WAMP它会去做。再也不用到处询问php的安装问题了,WAMP一切都搞定了。 8、Atom 功能介绍: ATOM,是一个现代的文本编辑器,平易近人,但可删节的核心工具定制做任何事,也可以使用有效不沾一个配置文件。 原文发布时间:2018年03月23日 作者:programmer_feng 本文来源:CSDN如需转载请联系原作者

优秀的个人博客,低调大师

Python全栈工程师(字符串/序列)

ParisGabriel Python 入门基础 字符串:str用来记录文本信息字符串的表示方式:在非注释中凡是用引号括起来的部分都是字符串‘’ 单引号“” 双引号''' ''' 三单引""" """ 三双引有内容代表非空字符串否则是空字符串 区别:单引号内的双引号不算结束符双引号内的单引号不算结束符三引号内的换行会自动转换为换行符三引号内可以包含单引号和双引号 隐式字符串拼接: s = "I'm a I'm a programmer" 'heoll "wored"' 转移符:\' 单引号\" 双引号\\ 单反斜杠\n 换行\r 返回光标至行首\t 水平制表符\v 垂直制表符\f 换页\b 倒退\0 空字符,字符值为0\xXX ,XX为两位16进制表示的自符\uXXXX ,XXXX为4个16进制的Unicode16字符\UXXXXXXXX ,8个16进制表示的Unicode32字符 ASCII编码:man ASCII:查看帮助文档命令 常用ASCII编码:字符 十进制 十六进制 0 48 0x30 A 65 0x41 a 97 0x61 Unicode:统一编码,分为Unicode16、Unicode32 序列的概念:字符串就是序列函数:len(x) 返回字符串的字符个数raw 字符串:让转义符号\无效格式:r‘字符串内容’print(r“\n\\\t”)字符串的运算:+ 用于拼接字符串* 用于生成重复字符串字符串的相乘只能与整数+= *= 与其他符合运算符相同in / not in 运算符:用于判断某个字符串是否在相当于字符串出现过 如果出现过返回true 否则返回false字符串的比较运算:> >= < <= == != 依次按照编码进行比较,直到最短字符串结束为止 索引(下标):Python的字符串是不可以改变字符序列的 index:字符串[整数表达式]Python序列都可以用索引来访问序列中的对象Python的序列正向索引是冲0开始的最后一个索引为len(s)-1Python序列的反响索引是从-1开始的 -1是最后一个 第一个是 -len(s) 切片:slice从一个字符串序列中取出相应的元素重新组成一个字符串系列语法:字符串序列[(开始索引b):(结束索引e):(步长s)]小括号括起的部分代表可省略说明:开始索引是切片开始切下的位置,0代表第一个元素,1代表第二个,-1代表最后一个结束索引是切片的终止索引(但不包括终止点)步长:是切片每次获取当前元素后移动的方向和偏移量没有步长,相当于取值完成后向右移动一个索引的位置默认1当步长代表为正数时取正向切片 步长默认为1 开始位置为0 结束为len(s)步长代表下一次索引的取值增长值当步长为负数时 取反向切片 默认的起始位置是最后一个元素,终止位置是第一个元素的前一个位置 Python3中常用于序列函数:len(x)返回序列长度 max(x)返回序列最大值元素 min(x)返回序列最小止元素 字符串编码转换函数:ord(c)返回一个字符的Unicode值(十进制) chr(i)返回 i这个整数的值所对应的字符 整数转字符串函数:bin(i) 将整数转换为二进制的字符串 oct(i) 将整数转换为八进制的字符串 hex(i) 将整数转换为十六进制的字符串 二进制转换其他进制是非常好转的 如图: 100=4 101=5 10=2 156=0o452 (八进制) 1100=c 1001=9 156=0x9c (十六进制) 字符串的构造函数:str(obj=“”) 将对象转换为字符串 常用的字符串方法:文档参见:对象.方法名(方法传参)"abc".isalpha() # 语法是对的123.isalpha() # 语法是错的方法 说明S.isdigit() 判断字符串中的字符是否全为数字S.isalpha() 判断字符串是否全为英文字母S.islower() 判断字符串所有字符是否全为小写英文字母S.isupper() 判断字符串所有字符是否全为大写英文字母S.isspace() 判断字符串是否全为空白字符S.center(width[,fill]) 将原字符串居中,左右默认填充空格 width:所居中字符串的长度 fill:默认填充空格 S.count(sub[, start[,end]]) 获取一个字符串中子串的个数 sub:所要获取的字符串 start:起始位置 end:结束位置S.find(sub[, start[,end]]) 获取字符串中子串sub的索引,失败返回-1 start:起始位置 end:结束位置 S.strip() 返回去掉左右空白字符的字符串S.lstrip() 返回去掉左侧空白字符的字符串S.rstrip() 返回去掉右侧空白字符的字符串S.upper() 生成将英文转换为大写的字符串S.lower() 生成将英文转换为小写的字符串S.replace(old, new[, count]) 将原字符串的old用new代替,生成一个新的字符串 count:更换的次数S.startswith(prefix[, start[, end]]) 返回S是否是以prefix开头,如果以prefix开头返回True,否则返回False,S.endswith(suffix[, start[, end]]) 返回S是否是以suffix结尾,如果以suffix结尾返回True,否则返回False 以下是不常用的 S.title() 生成每个英文单词的首字母大写字符串S.isnumeric() 判断字符串是否全为数字字符 练习:1.输入一个字符串用s绑定判断输入有几个人空格将原字符串的左右空格空白符去掉打印剩余的字符个数判断输入的是否是数字如果是数字判断这个数是否大于100 答案: print("Answer to question 1:", "\n") s = input("plaese input at will string:") print("you input string blank have ", s.count(" ")) print("string surplus:", len(s.strip())) if s.isdigit() is True: if int(s) > 100: print("input integer:", s, ">100") else: print("input integer:", s, "<100") else: print("you input contain alpha:", s) 2.输入3行文字,让这三行文字在一个方框内居中显示显示如下:+---------------+| hello || 123123 || |+---------------+注:请不要输入中文 答案: print("Answer to question 2:", "\n") a = input("plaese input at will string 1:") b = input("plaese input at will string 2:") c = input("plaese input at will string 3:") top = a if top < b: top = b if top < c: top = c print("+" + "-" * (len(top) * 2 + 10) + "+") print("|" + a.center(len(top) * 2 + 10) + "|") print("|" + b.center(len(top) * 2 + 10) + "|") print("|" + c.center(len(top) * 2 + 10) + "|") print("+" + "-" * (len(top) * 2 + 10) + "+")

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册