网站性能检测评分
注:本网站页面html检测工具扫描网站中存在的基本问题,仅供参考。
给python传递参数
学Python要学那些东西,可以往什么方向发展 互联网视频课程
学习Python的这几天来,觉得Python还是比较简单,容易上手的,就基本语法而言,但是有些高级特性掌握起来还是有些难度,需要时间去消化。Python给我最大的印象就是简洁,这也正是我为什么要从Java转行Python的原因之一。
一、Python简介
ython实现强势逆袭,而且我相信,随着时间的推移,国内Python语言未来前景也是一片向好。
Python的特点是优雅简单,易学易用(虽然我感觉还是有一些概念不容易理解),Python的哲学是尽量用最少的,最简单易懂的代码实现需要的功能。Python适宜于开发网络应用,脚本写作,日常简单小工具等等。Python的缺点是效率较低,但是在大量的场合效率却不是那么重要或者说Python不是其性能瓶颈,所以不要太在意。其次是2.x-3.x的过渡使得许多3.x还缺少很多2.x下的模块,不过也在完善中。其次就是源代码无法加密,发布Python程序其实就是发布源代码。
tiobe编程语言排行榜
一,函数
1.函数是对象,函数名即是指向对应函数对象的引用,所以可以将函数名赋给一个变量,相当于给函数起一个‘别名’。
2.Python函数可以返回”多个值“,之所以打引号,是因为实际上返回的多个值拼成了一个元组,返回这个元组。
3.定义默认参数需要牢记:默认参数必须指向不变对象。否则第一次调用和第二次调用结果会不一样,因为可变的默认参数调用后改变了。
4.可变参数:传入的参数个数是可变的,可以是0个或多个。可变参数会将你传入的参数自动组装为一个tuple。在你传入的list或tuple名字前加一个 * 即说明传入的是可变参数。习惯写法为*args。
5.关键字参数:传入0个或多个含参数名的参数,这些参数被自动组装成一个dict。习惯写法**kw,如**a表示把a中所有的键值对以关键字参数的形式传入kw,获得一个dict,这个dict是a的一份拷贝,对kw改动不会传递到a
6.命名关键字在函数定义中跟在一个*分割符后c,d为命名关键字参数,可以限制调用者可以传入的参数名,同时可以提供默认值
7.参数定义顺序:必选参数,默认参数,可变参数/命名关键字参数,关键字参数。
8.切片操作格式为lis[首下标:尾下标:间隔],如果都不填,即lis[::]则代表整个容器lis
9.用圆括号()括起来一个列表生成式创建一个生成器generator,generator保存生成算法,我们可以用next(g)取得生成器g的下一个返回值。生成器的好处就是我们不需要提前生成所有列表元素,而是需要时再生成,这在某些情况下可以节省许多内存。算法也可以不是列表生成式而是自定义函数,只需在函数定义中包含yield关键字。
10.map()和reduce(): 二者都是高阶函数。map()接收两个参数,一个是函数,一个是Iterable序列,map将传入的函数依次作用在序列每一个元素上,并把结果作为新的Iterator返回。reduce()类似累积计算版的map(),把一个函数作用在一个序列上,每次接收两个参数,将结果继续与序列的下一个元素做累积计算。
利用map和reduce编写一个str2float函数,如把字符串'123.456'转换成浮点数123.456:
11.fliter()函数过滤序列,类似于map()作用于每一元素,根据返回值是True或者False决定舍弃还是保留该元素。函数返回一个Iterator。
12.sorted()函数可实现排序,类似于C++库中的sort()函数,但是比其更加简洁,语法为sorted(lis,key=func,reverse=T/F)
key函数可实现自定义的排序规则,reverse表示升序还是降序。
13.一个函数可以返回一个函数,但是返回时该函数并未执行,所以返回函数中不要引用任何可能发生变化的变量,否则会出现逻辑错误。
14.装饰器(decorator): 当需要增强函数的功能却不希望修改函数本身,那么可以采用装饰器这种运行时动态增加功能的方式,增加的功能卸载装饰器函数中。如在执行前后打印'begin call'和'end call',可以这样做:
二,基础
1.如果一个字符串中有许多需要转义的字符,而又不想写那么多'',那么可以用 r'...' 表示 '...'内的内容不转义。
2.Python的逻辑运算and, or, not 分别对应C语言中的&&, ||, !.
3.Python的整数与浮点数大小都没有范围。
4.Python中除法有两种: '/'除出来必是浮点数, '//'除出来是整数,即地板除。
5.Python中一切皆引用。每个对象都有一个引用计数器(内部跟踪变量)进行跟踪,引用计数值表示该对象有多少个引用,当初次产生赋给变量时,引用计数为1,其后没进行下列行为中的任意一种都会增加引用计数
6.深拷贝与浅拷贝的概念与对比,有点复杂,看这篇文章
7.list,tuple和dict,set
list: 为列表,是一个有序集合,类似于数组但又比数组功能强大,可以随时append,pop元素,下标从0开始,且下标为加n模n制,即lis[-1] = lis[len-1],下标范围[-len,len-1].
tuple:为元组,类似于list,但list为可变类型,而tuple不可变,即没有append,pop等函数。一个建议是为了安全起见,能用tuple代替list尽量用tuple。如果tuple只有一个元素,要写成如(1,)以避免歧义。
dict:字典类型,存放key-value键值对,可以根据key迅速地找出value,当然,key必须是不可变类型
三,面向对象编程
1.Python实例变量可以自由地绑定任何属性
2.为了不让内部属性不被外部访问,在属性的名称前加上两个下划线__,这样就变成了一个私有变量(private),注意,不能直接访问不代表一定不能访问,事实上,加双下划线后Python就会将其改名为‘_class名__name’,所以还是可以这样来访问这个‘私有’变量。
3.对于静态语言,如果要求传入一个class类型的对象,那么传入的对象必须是class类型或者其子类,否则将无法调用class中的方法,而Python这样的动态语言有‘鸭子类型’一说,即不一定要传入class类型或其子类,而只要保证传入的对象中有要使用的方法即可。
4.如果想要限制实例可以绑定的属性,那么在定义class时定义一个__slots__变量即可。
5.@ property装饰器可以使一个getter方法变成属性,如果方法名为me,那么@me.setter装饰器则可使一个setter方法变成属性。这样可以使代码更简短,同时可对参数进行必要的检查。注意,__slots__限制的属性对当前类实例起完全限制作用,且与子类共同定义其__slots__,也就是说子类可以定义自己的__slots__,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__,即并集。
6.通过多重继承,可使子类拥有多个父类的所有功能。
7.在类中__call__方法可使实例对象像函数那样直接调用,作用即是该方法定义的过程。
8.ORM(Object Relational Mapping 对象关系映射),就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表。ORM的实现需要通过metaclass元类修改类的定义。元类可以改变类创建时的行为。
四,IO编程
1.序列化: 把变量从内存中变成可存储或传输的过程称之为序列化。Python用pickle模块实现序列化。序列化之后,就可以把序列化后的内容存储到磁盘上或者通过网络进行传输。pickle.dumps()将对象序列化成一个bytes,而pickle.loads()可以根据bytes反序列化出对象。
2.pickle虽好,但是它专为Python而生,所以要在不同语言间传递对象,最好还是xml或者json,而json表示格式是一个字符串,更易读取,且比xml快,所以更加适宜于对象序列化。Python内置了json模块,相应方法仍然是dumps()和loads()。
3.但是在默认情况下,有些对象是无法序列化的,所以我们有时还需要定制转换方法,告诉json该如何将某类对象转换成可序列为json格式的{}对象。如下即是一个转换方法:
五,调试
1.Python调试方法:
(1)直接打印
(2)断言
(3)pdb
(4)IDE
想学习从事Python工作的请关注小编
Python编程入门之深入了解函数定义默认参数值 推广视频课程
More on Defining Functions--- Default Argument Values
It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.定义函数时也可以添加一些参数.有三种形式,可以组合使用.
The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:为一个或多个参数指定默认值是最有用的形式.这样会创建一个函数,其参数可少于定义的数量.例如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries < 0:
raise IOError('refusenik user')
print(complaint)
This function can be called in several ways:这个函数可以几种方法被调用:
giving only the mandatory argument: ask_ok('Do you really want to quit?')
giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
This example also introduces the in keyword. This tests whether or not a sequence contains a certain value.这个例子中引用了关键字in.它将测试一个序列是否含有某个值.
The default values are evaluated at the point of function definition in the defining scope, so that will print 5.默认值在函数定义的范围内被赋值,所以此处将打印值5.
i = 5
def f(arg=i):
print(arg)
i = 6
f()
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:重要警告:默认值只被赋予一次.这在默认值为列表,字典或大部分类的实例等可变对象时会产生很大影响.例如,下面的函数将在子序列调用时积累传递给它的参数:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
This will print以上将打印以下结果
[1]
[1, 2]
[1, 2, 3]
If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:如果您不想和子序列调用共享默认值,您可以用以下写法替换:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
Python编程入门之函数可变参数 企业视频课程
Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see Tuples and Sequences). Before the variable number of arguments, zero or more normal arguments may occur.最后,最不常用的选项是指定函数可以用任意数量的参数来调用。这些参数将被封装在一个元组中(参见Tuples和序列)。在变量数目可变之前,可能出现零个或多个正常参数。
defwrite_multiple_items(file,separator,*args):file.write(separator.join(args))
Normally, these variadic arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.通常,这些变量参数将在正式参数列表中最后一个,因为它们获取传递给函数的所有剩余输入参数。在*args参数之后出现的任何正式参数都是“仅关键字”参数,这意味着它们只能用作关键字而不是位置参数。
>>> defconcat(*args,sep="/"):... returnsep.join(args)...>>> concat("earth","mars","venus")'earth/mars/venus'>>>concat("earth","mars","venus",sep=".")'earth.mars.venus'
Python下单元测试框架与unittest单元测试框架实现参数化(附源码) 营销视频课程
GitHub地址:https://github/wolever/nose-parameterized
当我们在使用TestNG时,发现它有一个非常好用的参数化功能。当你的测试用例有固定的参数和断言结果时,它可以相似用例的节省用例的个数。
例子如下:
import static org.testng.Assert.assertEquals;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Created by fnngj on 2017/3/19.
*/
public class Demo {
// 定义测试数据
@DataProvider(name = "data")
public Object[][] Users() {
return new Object[][] {
{ 1, 1, 2},
{ 2, 2, 5},
{ 3, 3, 6},
};
}
@Test(dataProvider="data")
public void testAdd(int a,int b,int c) {
assertEquals(a + b, c);
}
}
相对而言,Python下面单元测试框架要弱上少,尤其是Python自带的unittest测试框架,不支持参数化,不支持多线程执行用例,不支持HTML测试报告的生成...。好再,部分不足我们可以通过unittest扩展来满足需求。比如现在要介绍一个参数化的扩展。
在没有参数化功能的情况下,我们的用例需要这样编写。
import unittest
class TestAdd(unittest.TestCase):
def test_add_01(self):
self.assertEqual(1 + 2, 3)
def test_add_02(self):
self.assertEqual(2 + 2, 5)
def test_add_03(self):
self.assertEqual(3 + 3, 6)
if __name__ == '__main__':
unittest.main()
nose-parameterized是一个针对Python单元测试框架实现参数化的扩展。同时支持不同的单元测试框架。
GitHub地址:https://github/wolever/nose-parameterized
然后,unittest就可以像TestNG一样写用例了。
import unittest
from nose_parameterized import parameterized
class TestAdd(unittest.TestCase):
@parameterized.expand([
("01",1, 1, 2),
("02",2, 2, 5),
("03",3, 3, 6),
])
def test_add(self, name, a, b, c):
self.assertEqual(a + b, c)
if __name__ == '__main__':
unittest.main(verbosity=2)
执行结果:
test_add_0_01 (__main__.TestAdd) ... ok
test_add_1_02 (__main__.TestAdd) ... FAIL
test_add_2_03 (__main__.TestAdd) ... ok
当相同入参和断言结果的用例越多,这种写法用起来越爽!
以上是全部内容,只是善于分享,不足之处请包涵!爬虫基本的原理就是,获取源码,进而获取网页内容。一般来说,只要你给一个入口,通过分析,可以找到无限个其他相关的你需要的资源,进而进行爬取。
我也写了很多其他的非常简单的入门级的爬虫详细教程,
关注后,点击我的头像,就可以查看到。
欢迎大家一起留言讨论和交流,谢谢!
手把手 | 嫌Python太慢?并行运算Process Pools三行代码给你4倍提速! 公司视频课程
大数据文摘作品,转载要求见文末
作者 | Adam Geitgey
编译 | 元元、Lisa、Saint、Aileen
原文链接 | https://medium/@ageitgey/quick-tip-speed-up-your-python-data-processing-scripts-with-process-pools-cf275350163a
Python绝对是处理数据或者把重复任务自动化的绝佳编程语言。要抓取网页日志?或者要调整一百万张图片?总有对应的Python库让你轻松完成任务。
然而,Python的运营速度一直饱受诟病。默认状态下,Python程序使用单个CPU的单个进程。如果你的电脑是最近十年生产的,多数情况下会有4个及以上CPU核。也就是说,当你在等程序运行结束的时候,你的计算机有75%或者更多的计算资源都是空置的!
让我们来看看如何通过并行运算充分利用计算资源。多亏有Python的concurrent.futures模块,仅需3行代码就可以让一个普通程序并行运行。
一般情况下的Python运行
比如说我们有一个文件夹,里面全是图片文件,我们想给每一张图片创建缩略图。
下面的短程序中我们使用Python自带的glob 函数获取一个包含文件夹中所有图片文件的列表,并用Pillow图片处理库获取每张图片的128像素缩略图。
这个程序遵循很常见的数据处理模式:
1. 从您想处理的一系列文件(或其他数据)开始
2. 编写一个处理一个数据的辅助函数
3. 用for循环调动辅助函数,一个一个的去处理数据
让我们用1000张图片来测试这个程序,看看运行时间是多少。
程序运行时间8.9秒,但是计算机的运算资源占用了多少呢?
让我们再跑一次程序,同时查看活动监视器:
计算机有75%空置,这是为什么呢?
问题在于我的计算机有4个CPU核,但是Python只用了其中一个核。即便我的程序把那个CPU核完全占满,但是其他3个CPU核什么也没干。我们需要想办法把整个程序的工作量分成4份然后平行运行。所幸Python可以做到这一点!
让我们来试试并行运算
下面是实现并行运算的一个方法:
1.把Jpeg图片文件列表分成4个部分。
2. 同时跑四个Python解释器。
3. 让四个解释器分别处理一部分图片文件。
4. 汇总四个解释器的结果得到最终结果。
四个Python程序分别在4个CPU上运行,跟之前在1个CPU运行相比大概可以达到4倍的速度,对不对?
好消息是Python可以帮我们解决并行运算麻烦的部分。我们仅需要告诉 Python我们想要运行什么函数以及我们希望工作分成多少份,其他部分留给Python。我们只需要修改三行代码。
首先,我们需要导入concurrent.futures库。这个库是Python自带的:
然后,我们需要告诉 Python另外启动4个Python实例。我们通过创建Process Pool来传达指令:
默认设置下,上面的代码会给计算机的每一个CPU创建一个Python进程,所以如果您的计算机有4个CPU,就会开启4个Python进程。
最后一步是让Process Pool 用这4个进程在数据列表中执行我们的辅助函数。我们可以把我们之前的for循环替代为:
新代码是调用executor.map()函数
executor.map() 函数调用时需要输入辅助函数和待处理的数据列表。这个函数帮我们完成所有麻烦的工作,把列表分成几个小列表,把小列表分配给每个子进程,运行子进程,以及汇总结果。干得漂亮!
我们也可以得到每次调用辅助函数的结果。executor.map()函数以输入数据顺序返回结果。 Python的zip()函数可以一步获取原始文件名以及相应结果。
下面是经过三步改动之后的程序:
让我们试着运行一下,看看有没有缩短运行时间:
2.274秒程序就运行完了!这便是原来版本的4倍加速。运行时间缩短的原因正是我们这次用4个CPU代替了1个CPU。
但是如果您仔细看看,您会看到“用户(User)”时间大概是接近9秒,如果程序2秒就运行结束了,为什么客户时间会是9秒?这似乎…有哪里不对?
其实这是因为”用户”时间是所有CPU时间的总和。我们和上次一样,用9秒的总CPU
注意:启用Python进程以及给子进程分配数据都会占用时间,因此您不一定能靠这个方法大幅提高速度。如果您处理的数据量很大,这里有一篇“设置chunksize参数的技巧”文章可能可以帮助您:https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.map。
这种方法总能帮我的程序提速吗?
当你有一列数据,并且每个数据都可以独立处理的时候,使用Process Pools是一个好方法。这有一些适合使用并行处理的例子:
从一系列单独的网页服务器日志里抓取数据。
从一堆XML,CSV和JSON文件中解析数据。
对大量图片数据做预处理,建立机器学习数据集。
但Process Pools不是万能的。使用Process Pool需要在独立的Python处理过程中将数据来回传递。如果你正在使用的数据不能在处理过程中有效的被传递,这种方法就行不通。你处理的数据必须是Python知道怎么搞定的类型(https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled)。
同时,数据不会按照一个预想的顺序被处理。如果你需要前一步的处理结果来进行下一步骤,这种方法也行不通。
那GIL怎么办?
你可能听说过Python有一个全局解释器锁(Global Interpreter Lock,),缩写为GIL。这意味着即使你的程序是多层的,每一层也只有一个Python命令能被执行。GIL确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势。
但Process Pools能解决这个问题!因为我们在运行单独的Python实例,每个实例都有自己的GIL。这样你就有了真正的并行处理的Python代码!
不要害怕并行处理!
有了concurrent.futures库,Python可以让你简简单单地修改脚本,却能立刻调用你电脑上所有CPU内核开足马力地运行。不要害怕尝试。一旦你会用了,它就像写一个for循环那样简单,但会让整个程序快很多。
Python函数学习之参数列表解包 企业视频课程
The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:当参数已经在列表或元组中时,相反的情况发生,但需要为需要单独位置参数的函数调用解包。例如,内置的Range()函数需要单独的开始和停止参数。如果它们单独不可用,则用*-运算符编写函数调用,以从列表或元组中解开参数:
>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
In the same fashion, dictionaries can deliver keyword arguments with the **-operator:以同样的方式,字典可以用**运算符传递关键字参数 即**-操作符来解包参数:
>>> def parrot(voltage, state='a stiff', action='voom'):
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>>parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
python之函数默认参数及注意点 公司视频课程
前言
在python中,函数的参数有多种类型,有默认参数、可变参数、关键字参数、命名关键字参数等,本文主要深入讲解默认参数。对于默认参数,其实在功能上就是为了简化函数调用。
默认参数
1、格式
2、说明及注意点
a. 在使用缺省参数后,对于函数的必填参数必须在前,默认参数在后。
b. 默认参数在一个函数中可以有多个。
c. 当一个函数中的某个参数的改动不大,就可以考虑将这个参数设置为默认参数,比如说一个人的民族,这种参数就可以设置为缺省参数。
案例a
小总结:从上图可以看出,对于num2这个参数如果你要传入的参数是100,则可传可不传,都是可以的。这个也是默认参数给我们带来的方便之处。
python中print语句
结论:其实在python中的print语句就是采用了缺省参数。
使用可变类型作为缺省参数
1、代码举例
结论:上图中的程序运行结果是[10],[20], 但是实际上结果是[10],[10,20]。问题的原因主要在于scores的类型是一个列表,本身是一个可变类型,那么对于列表的append方法添加元素的时候并不会对socres进行重新创建一个新的列表,那么也就是说,你两次append元素,其实都是对同一个列表进行操作。
总结
对于默认参数,如果是不可变类型,那么多次对函数的调用是没有问题的。
对于默认参数,如果是可变参数,那么对于参数的传递,就要特别考虑结果是正确性,所以对于这种情况,就必须在调用函数的时候就要重新初始化一次列表。