python案例2

        

python

python子类调用父类的方法

python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找。

继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的。

子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。

结果:

在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的namea属性的代码,为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数。

方法一:调用未绑定的超类构造方法

修改代码,多增一行:

如上有注释的一行解决了该问题,直接使用父类名称调用其构造函数即可。

这种方法叫做调用父类的未绑定的构造方法。在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类的方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。

通过将当前的实例作为self参数提供给未绑定方法,B类就能使用其父类构造方法的所有实现,从而namea变量被设置。

方法二:使用super函数

修改代码,这次需要增加在原来代码上增加2行:

扫描二维码关注公众号,回复: 664245 查看本文章

如上有注释的为新增的代码,其中第一句让类A继承自object类,这样才能使用super函数,因为这是python的“新式类”支持的特性。当前的雷和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。

super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类。

 方法一更直观,方法二可以一次初始化所有超类

super函数比在超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.__init__(self)更直观一些。

Python生成文件md5校验值函数

linux有个命令叫做md5sum,能生成文件的md5值,一般情况下都会将结果记录到一个文件中用于校验使用,比如会这样使用:

其中md5sum -c用于检测生成的md5值是否正确。

 

使用python生成文件md5值以及生成和md5sum结果一样的结果文件

python可以使用hashlib的md5模块对文件内容进行md5校验码生成,如果要生成和md5sum一样的结果文件,只需要将MD5结果值和文件名输出一行,中间有两个空格输出即可。

测试代码:

 

运行结果:

 

 

注意点

在windows下开发的代码,如果直接提交到linux运行,经常因为windows下的换行符是\r\n而linux是\n的缘故导致代码执行失败,一般情况下都要进行一下转换。

Hadoop-Streaming实战经验及问题解决方法总结

目录

1.   Join操作分清join的类型很重要…

2.  启动程序中key字段和partition字段的设定…

3.  控制hadoop程序内存的方法…

4.   对于数字key的排序问题…

5.   在mapper中获取map_input_file环境变量的方法…

6.   运行过程中记录数据的方法…

7.  多次运行Hadoop之是否成功的判断…

8.  对stdin读取的 line的预处理…

9.  Python字符串的连接方法…

10.  怎样查看mapper程序的输出…

11.  SHELL脚本中变量名的命名方法…

12.  提前设计好流程能简化很多重复工作…

13.  其他一些实用经验…

1. Join操作分清join的类型很重要

Join操作是hadoop计算中非常常见的需求,它要求将两个不同数据源的数据根据一个或多个key字段连接成一个合并数据输出,由于key字段数据的特殊性,导致join分成三种类型,处理方法各有不同,如果一个key在数据中可以重复,则记该数据源为N类型,如果只能出现一次,则记为1类型。

1)  类型1-1的join

比如(学号,姓名)和(学号,班级)两个数据集根据学号字段进行join,因为同一个学号只能指向单个名字和单个班级,所以为1-1类型,处理方法是map阶段加上标记后,reduce阶段接收到的数据是每两个一个分组,这样的话只需要读取第一行,将非key字段连到第二行后面即可。

每个学号输出数据:1*1=1个

2)  类型1-N或者N-1的join

比如(学号,姓名)和(学号,选修的课程)两个数据集根据学号字段的join,由于第二个数据源的数据中每个学号会对应很多的课程,所以为1-N类型join,处理方法是map阶段给第一个数据源(类型1)加上标记为1,第二个数据源加上标记为2。这样的话reduce阶段收到的数据以标记为1的行分组,同时每组行数会大于2,join方法是先读取标记1的行,记录其非key字段Field Value 1,然后往下遍历,每次遇到标记2的行都将Field Value 1添加到该行的末尾并输出。

每个学号输出数据:1*N=N*1=N个

3)  类型M-N的join

比如(学号,选修的课程)和(学号,喜欢的水果)根据学号字段做join,由于每个数据源的单个学号都会对应多个相应数据,所以为M*N类型。处理方法是map阶段给数据源小的加上标记1(目的是reduce阶段的节省内存),给数据源大的加上标记2,reduce阶段每个分组会有M*N行,并且标记1的全部在标记2的前面。Join方法是先初始化一个空数组,遇到标记1的行时,将非key数据都记录在数组中,然后遇到标记2的行时,将数组中的数据添加在该行之后输出。

每个学号输出数据:M*N个

2. 启动程序中key字段和partition字段的设定

在join计算过程中,有两个字段非常的重要并需要对其理解,就是排序字段key和分区字段partition的指定。

字段 字段说明

num.key.fields.for.partition

用于分区,只影响数据被分发到哪个reduce机器,但不影响排序

stream.num.map.output.key.fields

Key的意思就是主键,这个主键会影响到数据根据前几列的排序
org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 如果需要对字段排序、分区,默认都得加上此设置

上面三个配置尤其会影响到join计算时的配置:

1)  如果是单key的join,因为要加上标记字段排序,所以设定key=2,同时设定partition=1对第一个字段分区来保证同Key的数据都在同一台机器上;

2)  如果是N个联合key的join,首先需要加上标记字段,所以设定key=N+1,用来对其进行排序,然后需要partition为N来对其按key分区。

3. 控制hadoop程序内存的方法

Hadoop程序是针对海量数据的,因此任何一个保存变量的操作都会在内存中造成N倍的存储,如果尝试用一个数组记录每一行或某些行的单个字段,用不到程序运行结束,hadoop平台就会爆出137内存超出的错误而被kill掉。

控制内存的方法就是少用变量、尤其数组来记录数据,最终实现当前行的处理与数据总规模的无关,汇总、M*N的join等处理不得不记录历史数据,对这种处理要做到用后及时释放,同时尽量记录在单变量而不是数组中,比如汇总计算可以每次记录累加值,而不是先记录所有的元素最后才汇总。

4. 对于数字key的排序问题

如果不加以处理,排序处理过程中数字1会排在10之后,处理方法是需要在数字前面补0,比如如果全部有2位,就将个位数补1个零,让01和10比较,最终reduce输出的时候,再转回来,需要先预测数字的位数。

在mapper.py中:

Print ‘%010d\t%s’%(int(key),value)

其中key既然是数字,就需要用数字的格式化输出%010d表示将输出10位的字符串,如果不够10位,前面补0。

在reducer.py中,最终输出时,使用转int的方法去掉前面的0:

Print ‘%d\t%s’%(int(key),value)

5. 在mapper中获取map_input_file环境变量的方法

在mapper中,有时候为了区分不同的数据文件来源,这时候可以用map_input_file变量来记录当前正在处理的脚本的文件路径。以下是两种判别方法:

a)        用文件名判断

Import os

filepath = os.environ[“map_input_file”]
filename = os.path.split(filepath)[-1]

if filename==”filename1”:

#process 1

elif filename==”filename2”:

#process2

b)        用文件路径是否包含确定字符串判断

filepath = os.environ[“map_input_file”]

if filepath.find(sys.argv[2])!=-1:

#process

6. 运行过程中记录数据的方法

Hadoop程序不同于本地程序的调试方法,可以使用错误日志来查看错误信息,提交任务前也可以在本地用cat input | mapper.py | sort | reducer.py > output这种方法来先过滤基本的错误,在运行过程中也可以通过以下方法记录信息:

1)  可以直接将信息输出到std output,程序运行结束后,需要手工筛选记录的数据,或者用awk直接查看,但是会污染结果数据

2)  大多采用的是用错误输出的方法,这样运行后可以在stderr日志里面查看自己输出的数据:sys.stderr.write(‘filename:%s\t’%(filename))

7.  多次运行Hadoop之是否成功的判断

如果要运行多次的hadoop计算,并且前一次的计算结果是下一次计算的输入,那么如果上一次计算失败了,下一次很明显不需要启动计算。因此在shell文件中可以通过$?来判断上一次是否运行成功,示例代码:

if [ $? –ne 0 ];then

   exit 1

fi

8. 对stdin读取的 line的预处理

Mapper和reducer程序都是从标准输入读取数据的,然而如果直接进行split会发现最后一个字段后面跟了个’\n’,解决方法有两种:

1)  datas = line[:-1].split(‘\t’)

2)  datas=line.strip().split(‘\t’)

第一种方法直接去除最后一个字符\n,然后split,第二种方法是去除行两边的空格 (包括换行),然后split。个人喜欢用第二种,因为我不确定是否所有行都是\n结尾的,但是有些数据两边会有空格,如果strip掉的话就会伤害数据,所以可以根据情景选用。

9. Python字符串的连接方法

Mapper和reducer的输出或者中间的处理经常需要将不同类型的字符串结合在一起,python中实现字符串连接的方法有格式化输出、字符串连接(加号)和join操作(需要将每个字段转化成字符类型)。

使用格式化输出:’%d\t%s’%(inti,str)

使用字符串的+号进行连接:’%d\t’%i+’\t’.join(list)

写成元祖的\t的Join:’\t’.join((‘%d’%i, ‘\t’.join(list)))

10. 怎样查看mapper程序的输出

一般来说,mapper程序经过处理后,会经过排序然后partition给不同的reducer来做下一步的处理,然而在开发过程中常常需要查看当前的mapper输出是否是预期的结果,对其输出的查看有两种需求。

需求一,查看mapper的直接输出:

在运行脚本中,不设定-reducer参数,也就是没有reducer程序,然后把-D mapred.reduce.tasks=0,即不需要任何reduce的处理,但是同时要设定-output选项,这样的话,在output的目录中会看到每个mapper机器输出的一个文件,就是mapper程序的直接输出。

需求二,查看mapper的输出被partition并排序后的内容,即reducer的输入是什么样子:在运行脚本中,不设定-reducer参数,也就是没有自己的reducer程序,然后把-D mapred.reduce.tasks=1或者更大的值,即有reduce机器,但是没有reducer程序,hadoop会认为有reducer是存在的,因此会继续对mapper的输出调用shuffle打乱和sort操作,这样的话就在output目录下面看到了reducer的输入文件,并且数目等于reducer设定的tasks个数。

11. SHELL脚本中变量名的命名方法

如果遇到很多的输入数据源和很多输出的中间结果,每个hadoop的输出都会用到下一步的输入,并且该人物也用到了其他的输出,这样的话最好在一个统一的shell配置文件中配置所有的文件路径名字,同时一定避免InputDir1、InputDir2这样的命名方法,变量命名是一种功力,一定要多练直观并且显而易见,这样随着程序规模的增加不会变的越来越乱。

12. 提前设计好流程能简化很多重复工作

近期自己接到一个较为复杂的hadoop数据处理流程,大大小小的处理估算的话得十几个hadoop任务才能完成,不过幸好没有直接开始写代码,而是把这些任务统一整理了一下,最后竟然发现很多个问题可以直接合并成一类代码处理,过程中同时将整个任务拆分成了很多小任务并列了个顺序,然后挨个解决小任务非常的快。Hadoop处理流程中如果任务之间错综复杂并相互依赖对方的处理结果,都需要事先设计好处理流程再开始事先。

13. 其他一些实用经验

1)  Mapper和reducer脚本写在同一个Python程序,便于对比和查看;

2)  独立编写数据源的字段信息和位置映射字典,不容易混淆;

3)  抽取常用的如输出数据、读入数据模块为独立函数;

4)  测试脚本及数据、run脚本、map-reduce程序分目录放置;

 

 

Django基本命令最全收集

Django是一个python用于快速开发web应用的框架,它的很多特性使用极其方便快捷。当创建一个django项目和对项目进行管理的时候,会涉及到很多命令行命令。本文对其进行一些总结,以供方便查询。

django-admin.py startproject mysite

该命令在当前目录创建一个 mysite 目录。

django-admin.py这个文件在C:\Python27\Lib\site-packages\django\bin文件夹里,可以把该目录添加到系统Path里面。

Django内置一个轻量级的Web服务器。

进入 mysite 目录的话,现在进入其中,并运行 python manage.py runserver 命令

启动服务器,用http://127.0.0.1:8000/可以进行浏览了,8000是默认的端口号。

python manage.py runserver 8080

更改服务器端口号

python manage.py shell

启动交互界面

python manage.py startapp books

创建一个app,名为books

python manage.py validate

验证Django数据模型代码是否有错误

python manage.py sqlall books

为模型产生sql代码

python manage.py syncdb

运行sql语句,创建模型相应的Table

python manage.py dbshell

启动数据库的命令行工具

manage.py sqlall books

查看books这个app下所有的表

python manage.py syncdb

同步数据库,生成管理界面使用的额外的数据库表

Django关于站点管理Admin Site的常见问题解决方法

1. 改变django默认语言的方法?

仅需添加’django.middleware.locale.LocaleMiddlewar’到 MIDDLEWARE_CLASSES设置中,并确保它在’django.contrib.sessions.middleware.SessionMiddleware’* 之后* 。

2. 怎样将已有models加入到admin管理中?

本问题用实例演示,假如有个app叫做books,该app包里包含3个模块Publisher、Author和Book,以下是将该三个模块添加到admin管理中的步骤:

 books 目录下( mysite/books ),创建一个文件: admin.py

在admin.py中输入以下代码

from django.contrib import admin

from mysite.books.models import Publisher, Author, Book

#以下3句,实现将模块添加到后台管理

admin.site.register(Publisher)

admin.site.register(Author)

admin.site.register(Book)

3) 重启服务器,刷新后台界面(比如http://127.0.0.1:8000/admin)发现添加成功

[Read more…]

对Django框架架构和Request/Response处理流程的分析

一、 处理过程的核心概念

如下图所示django的总览图,整体上把握以下django的组成:

django整体架构图

核心在于中间件middleware,django所有的请求、返回都由中间件来完成。

[Read more…]

Ubuntu10.10 Server+Nginx+Django+Postgresql安装步骤

1,安装Ubuntu 10.10

1.1 使用默认安装,在更新apt的时候选择跳过

1.2 设置管理员的用户名和密码

1.3 安装openssh-server启动ssh服务,方便使用Bitvise Tunnelier,putty工具进行管理

sudo apt-get install openssh-server

[Read more…]

Python模拟登陆新浪微博并实现投票功能

上次发了一篇文章,题目叫做《Python使用cookielib和urllib2模拟登陆新浪微博并抓取数据》,里面的代码请不要怀疑,我测试过它是正确的。

新浪微博的模拟登陆,有个前提条件,你用新浪微博账号登陆的时候,新浪没有提示你输入验证码。若需要输入验证码,不好意思这里不作处理,你可以用以下几种方法解决验证码问题:
1、用图片识别软件识别,不过识别正确率会很低
2、登陆的时候如果需要验证码,我们的自己的程序就弹出验证码的图片,自己手工输入
3、外包给验证码输入公司,比如100元,把图片传过去,他给你送回文字结果10000个

程序运行到了后面,我提到urllib2里面的cookie已经存放了我们请求任何页面需要的数据,因此可以用urllib2请求任何页面、发微薄、投票实现任何事情,详细见如下代码,猥琐的分隔栏下面是新增的内容,为了方便,我把上次的代码一起贴出来了,代码注释很给力,大家可以看一看,本代码测试成功:

 

Django中定制自己的User和Group管理模块(类似对admin的二次开发)

django的admin后台管理实在强大,其实对于普通模型来说倒没什么,关键是对于权限系统,比如User和Group的管理,它做的非常好,让人总是想要充分利用它本身的功能。

然而在admin后台上直接进行二次开发有很多不友好的地方,比如你如果简单的扩充了User表,却不能够在系统本身的User模型中管理添加的字段,这涉及到dj源码(修改源码绝对不是好主意)

因此必须得自己来写权限系统,其实这里我们是对django的contrib下面的auth进行接口编写,下面是示意图:

其实正是因为对Auth(包括User和Group)的增删改查和对Auth的使用(验证权限等)之间没有直接的关系,因此我们可以简单的把Django核心中的User和Group作为一个简单的模型来使用,比如对Group的添加、修改、删除等等。

而使用的时候,因为直接访问的还是核心,它并不知道我们偷偷的写了很多源码自己来操纵User和Group,一切皆数据,数据即中介,对User和Group的使用,知识对数据的简单访问而已。

思路已经理清,可以对User和Group做如下的操纵来实现自己的、类似于Admin站点管理的模块:我们要使用的,只是源码核心中的User和Group的模型类model,因此我们可以建立自己模型表单,哈哈,简单的访问该模型表单,我们就是对User和Group的数据进行操作,简单吧~。

django1.4设置模板路径和CSS,JS,image等路径的方法

对于DJANGO这类MVC框架来说,路径问题可以称为一个谜一样的东西,很多人因为对路径不知道如何处理而觉得MVC实在是云里雾里不知所云。

本文主要解决django中关于模板路径设置、CSS文件路径设置、JS文件路径设置、图片路径设置等常见问题。文中将templates和media(包含js、css、images目录)放到了项目目录的根目录,更具有一般性质。

设定模板路径

设置模板路径比较简单,只要在setting.py里面的TEMPLATE_DIRS选项里面加上这么一句话即可:

 

这意味着,你可以在项目的根目录下面,建立一个templates目录,里面放你所有的模板

设定CSS/JS/IMAGES等路径

1、在setting.py里面,加入下面一句话,指定根目录下面的media路径:

 

2、在urls.py里面设定这么一句话,将请求CSS/JS/IMAGES的URL转到该地方

 

3、那么在我们的模板里面,现在已经可以用以下方法访问JS/CSS/IMAGES

 

该方法的一个优点是,不用详细设置JS、CSS、images三个不同的路径,只要设定一个,在模版文件里面,直接指定文件的子目录就可以了,比如图片和JS可以这么写:

<img src=’/site_media/images/a.jpg’>

<script src=’/site_media/js/s.js’> </script>

请看这里,我们并没有在urls.py中指定/site_media/images这样的路径。

猜你喜欢

转载自hugoren.iteye.com/blog/2288157
今日推荐