Python

python type

September 22, 2018
Python

type 的普通用法 # type一般的用法使用来获取一个变量的类型,但是,type并不适合用来获取一个变量的类型。 想获取一个变量的类型,有其实类的实际类型要用isinstance isinstance # class A: pass class B(A): pass isinstance(A(), A) # returns True type(A()) == A # returns True isinstance(B(), A) # returns True type(B()) == A # returns False a = 111 isinstance(a, int) # True python中有一种old-style class 这些类用type直接取得到的都是instance, 也就是所有的类实例都是一样的。在后来的new-style class中,得到的会有区别但是,依然不能很好的判断子类的问题。 type 创建一个类型 # 这个用法我看到的时候反正是一脸懵逼,莫非是用来动态创建类用的? 用法: #type(classname,(parents,...),{attribute}) #第一个参数classname是类名,第二个是一个父类元组,没有可填空元组,第三个参数是类属性字典。 #!/usr/bin/env python # coding=utf-8 class XA(object): a = 1 XB = type('XC', (object, ), dict(a=3)) Xa = XA() Xb = XB() # Xc = XC() # syntax error, there is no such a class named XC, only XB as a llegal class name. ...

python 多线程和异步

September 21, 2018
Python, Multithreaded

python 的多线程还有协程这种东西。 线程池 # 关于多线程的实现,各种语言基本上都是一样的。 一种是集成一个线程的基类,然后重写一个run()函数。这类写法比较好理解,非常直观就是创建一个线程交给操作系统。 因为每个线程都有确定的程序起点、执行顺序、程序终点。因此这个函数就是起点。 另外一种就略有区别,Java中就是实现一个接口,在python中没有接口就是直接传个函数去构造出一个线程。Java中的接口其实很不好理解,因为这个接口只是实现了一个逻辑在run()函数里, 实例化这个类的时候并没有创建这个线程,还要单独用这个类的实例去再实例化一个线程。然后在start这个线程。 无论是那一种,在底层都是一样的。就是把一段逻辑写进一个函数中,作为一个起点用来生成一个线程资源。而这个工作,都是基类Thread来实现的。 因此只要给Thread类一个程序入口就可以构造出一个线程了。 线程的启动和设定都很好解决。有一个问题就是创建线程也是要话费时间的。因此就有线程池的思想。 线程池的优点: 避免线程的创建和销毁带来的性能开销。 避免大量的线程间因互相抢占系统资源导致的阻塞现象。 能够对线程进行简单的管理并提供定时执行、间隔执行等功能。 两个单词区分一下:async(异步)、 sync(同步)

tensorflow

April 12, 2018
TF, Python

引言 # Tensorflow究其本质还是一个编程框架,只是这个框架主要面向机器学习和深度学习领域。我们应该还是要使用学习框架的方法来学习他。 很多时候我们要先分清楚问题的主要矛盾是什么。 在很久以前,我学习视频剪辑。那个时候我对于视频剪辑一窍不通,好不容易安装上pr又要开始漫长的学习怎么使用。 我看了很多的视频和博客,教我如何使用这个软件,面对错综复杂的按钮和组合操作,我不知道什么东西在哪,有什么作用。当我明白了什么工具在什么位置的时候,我发现我依然不会做视频。 后来,我想到了,我从来就不懂如何剪辑视频,而不是不会使用这个软件。 如果我清楚的明白调整alpha通道会产生什么效果等一系列参数的作用,我自然就会明白的当前需要做什么,需要改变什么值,去找对应的按钮,而找对应的按钮只要很简单的搜索一下就可以了。 所以,软件并非是为了我这样的小白设计的,而是为专业的人设计的,因此我才会看着琳琅满目的按钮不知所措。 很多刚准备入门机器学习和深度学习的同学,大家的问题可能并不是不会使用Tensorflow这个框架,而是不会设计Model,不懂一个Model需要先做什么后做什么,在什么层次需要应用什么函数来达到效果。 换个角度来说,就算熟悉的掌握了Tensorflow的每个函数如何调用,也未必就能实现神经网络。 因此,Tensorflow做为一个框架,并不是让你对每个函数都了如指掌,而是当你想做什么动作的时候,知道框架中已经实现了这个功能,你知道要去寻找什么。而寻找对应的函数,就是很简单的问题了,然后再经过几次使用,你就完全可以记住了。 学习框架就是要理解它的哲学 # 框架为我们提供了一些功能上的便利,为了实现功能的通用性和可扩展性,框架需要一些辅助机制,来确保可扩展性和通用性。 Tensorflow这类算法的框架,相比较复杂的业务工程类框架要简单很多。 Tensor: 张量 flow : 流 他的名字已经揭示了他的核心逻辑。Tensorflow 中的计算使用一个有向图(计算图)来表示。其中每个运算操作作为一个点,点与点之间连边,数据就是这里的Tensor,Tensor在其中流转,最终完成计算。 一个计算图描述了一个计算的流程,没个点可以有任意多的输入和输出。有一些边并不是用来流转数据的,而是用来依赖控制,用来保持数据在正确的时间被运算。 因此我们的代码中,大部分是在描述一个计算图,而当这个计算图被描述完毕后,需要触发一个Session来执行这个计算图。 我们不能事无巨细的讲解框架中的设计逻辑。这里我们简要介绍比较重要的几个元素,是深入学习之前必须先搞透的东西。 Variable # Variable是一类特殊的运算操作,每次执行计算图后,Variable中的数据tensor会被保存下来,同时在计算的过程中也会被更新,比如神经网络的系数,每次训练都会被更新,最后会被保存下来。 Session # TensorFlow执行计算图需要实例化一个Session类来执行。调用Session的run方法,他可以自动计算所需计算的节点并按照依赖顺序计算他们,并且每个Session持有一些资源, 比如Variable,在计算结束的时候,我们要关闭Session以减少开销。 小经验 # 学习框架有一些方法,是很多实践总结下来的经验,分享一下。 过程 # 学习框架的过程大致是这样的: 理解核心概念/理念 -------> 入门经典代码/项目 -------> 核心类的代码 (设计哲学) (加深理解) (这些代码会大体勾勒出整个框架的逻辑) | | V ----------> 更复杂的代码/项目 | (学习如何使用/最佳实践) | | | | | V |__________ 更多核心类的实现 (会让你对每个部分设计目的更清晰, 帮助你融会贯通) 方法 # 前期刚接触的时候,多看博客,开始接触代码后,学会用好源码。 注意!这里的源码并不代码,而是源代码中的注释! 框架的代码都是相对规范的,在核心的类中都有非常详细的注释,解释了该类的作用、调用方式、特点、注意事项等,还可以直观的看到参数的情况。很多框架的API文档其实就是这些注释换个地方给你而已。 因此与其看文档,有的时候源代码会更好用。当然你需要熟练的使用IDE和代码跳转。 ...

Tutorial of anaconda & 原生虚环境

March 28, 2018
Python

什么是conda? # anaconda是一个用于科学计算的python发行版。其中预置了一些用于科学计算的库,诸如numpy等。 并且包含一个包管理系统,可以方便的安装相关的库。 我使用conda主要是搭建机器学习的环境。 Install # 在conda的download页面找适合自己的安装包下载,在Ubuntu上会得到一个bash脚本文件。 也可以使用命令: wget https://repo.continuum.io/archive/Anaconda2-5.1.0-Linux-x86_64.sh 然后使用root权限运行就可以了。 在运行的过程中,会询问你一些设置方案,如安装的路径、是否要添加进入PATH等。 检查是否安装成功 # 使用命令: python -V 出现: Python 2.7.14 :: Anaconda, Inc. 说明安装成功 使用conda创建自己的开发环境 # 学过python的都知道,py的版本兼容实在太随意了。因此py为了解决同一台电脑上需要不同py环境的问题,设计了一个虚环境。也就是我们可以创建一个虚环境,然后进入这个虚环境安装我们需要的包,这些包的作用范围就是在这个环境中。 因此也就实现了环境隔离。 一般我们在开始一个开发的时候,都会先创建一个虚环境。 使用conda创建tenserflow训练环境 # # 创建名为:nlpcc-1.0 的虚环境 # 指定python版本为2.7, tensorflow版本为1.0的gpu版, # 需要安装anaconda conda create -n nlpcc-1.0 -c anaconda tensorflow-gpu=1.0 python=2.7 # 为当前环境安装包 conda install numpy # 升级包的版本 conda update numpy # 删除包 conda remove numpy # 列出当前环境的包 conda list # 删除一个环境 conda remove --name nlpcc-1. ...

Django

July 6, 2017
Python, Django, Web

(注:本文写在N天之中,随着对其的深入学习,很多的看法会发生变化。我也尽量把东西放在这一篇中解决掉,文章思路会有些跳跃,可能先上了细节后面再归档等等。另外,本文会屏蔽一些技术细节,用一些术语来表达,这些术语均是较容易学习的知识块。) 这段时间神奇的技术走位,Java与Python的爱恨交织。 所以既然写到了肯定就是用到了呗,拿到了一个Django的项目,改写成Java的,玩的就是这么欢脱,做为一个写C++出身的入门级Java工程师生活已经如此艰难,然后发现现实是还要兼职Python工程师。 Django也算是工程师玩的玩意儿?封装成了这个样子还有什么好玩的,估计随随便便学2个小时语法加一点Django的框架设计就可以玩起来的,我只能说写这项目的哥们太会偷懒了,服气,骗完钱就离职,更是任性的不行。 言归正传!框架这种东西嘛,就是为了简化开发,提高速度效率,降低合作成本用的,所以django的设计也算是符合了这个目的。但是他并不是简单的照搬了JavaWeb框架的MVC设计思路,而是他妈的又提出了一个神奇的MTC,不用想也知道,就在人家的基础上变来变去还自以为参透了宇宙的奥秘。所谓的MTV就是把几个分工重新分了一下,对,就是要跟人家不一样,日你哥! 不过话回来,就算是对于MVC这个业界都普遍遵循的设计模式,也有很多不同的理解,比如业务逻辑到底该Controller来做还是Model来做,甚至还有人要把这个交给view来做的。之前貌似还看到了个文章讲什么官方设定,话说都发展到这个地步了谁还管你官方设定。不过呢,这都是个设计思路,不同的程序员当然有自己的理解,自己写项目的时候怎么搞都行,但是现在这框架数量真的有点爆炸了,所以大家还是在设计的时候多用点心吧,实现框架的技术不难,但是设计是艺术。 所谓的MTV分别就是: Model、Templete、View。熟悉就对了,你肯定一眼就看懂了,我也是一瞬间就明白了。但是很抱歉,仔细想一下这个Templete如果是前端模板的话,view是啥?如果view用来组装前端模板的话,要model来做业务逻辑吗?那controller岂不是没有了?……就是这么神奇,人家把业务逻辑交给了view来做,我特么也是佩服的吐血。Model就纯纯的数据库操作,就像是一个sql的python版。至于Templete,我已经没有耐心再跟他浪费时间了,老子一个写接口的要什么前端! 对于理解一个框架来说什么最重要?我在很久以前初学框架的时候一脸懵比。我草,这么多代码我得看到什么年?怎么连个主函数都没有,日了狗。。。好在我当时看了一会php,这个比较简单,不用编译一下就能懂,后来我从别人的文章中看到了学习框架的几个步骤等,才知道,看懂路由,就懂了这个框架的一半。 路由 # 提到这个路由,Python这个框架还是让我吃了一惊的。因为这玩意儿不需要容器,厉害啊。写过其他Web的都知道,我们的Web程序是要在一个Web服务程序的组织下做应答的。但是Django抛弃了这个服务程序,严格来说是Python的Web Server抛弃了其他的服务程序,自己写了一个简单的网关程序–wsgi。其实作用就是做个协议转换,链接机器与python程序,替代了apache2的一些基础功能。不过据说性能欠佳,做做测试还行,上线还是要靠Nginx的帮助,搞个uwsgi。 底层的东西,可以不懂,但是懂一定没有坏处,但是我还没时间搞懂。下面讲一下上层路由。 一个Django的项目特点就是目录比较清晰,比如这个urls.py就是存放路由信息的文件。django在自动化这个地方并没有做太多东西,对于路由信息要显示的写在这里。for一个zample. from django.conf.urls import url, include from django.contrib import admin import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^docs/', include('rest_framework_docs.urls')), url(r'^er/', views.ERView), # ui view url(r'^ui/Node', ui_views.node_view), url(r'^ui/Cluster', ui_views.cluster_view), url(r'^ui/InstanceGroup', ui_views.instance_group_view), url(r'^ui/Chart', ui_views.chart_view), url(r'^ui.*', ui_views.home_view), # API url(r'^v1/', include('rest_api.urls')), url(r'^v2/', include('rest_api.urls_v2')), #url(r'^report/', include('report.urls')), url(r'^.*', include('rest_framework_docs.urls')), ] 路由中可以预留参数位置,可以写正则表达式,论灵活性也还行。看到有些东西后买你跟的不是一个类,而是一个import语句,这是将路由转移到这个新的应用中去了,所以要去这个应用下再找对应的文件去继续路由,直到找到某个类为止。上面这个程序中其实是用到了一个叫rest_framwork的东西,这个玩意貌似是用来写网页文档用的东西,不过这个不是重点。 既然找到了这个类,那么有个经典的问题又来了。去调用那个函数啊?这就涉及到了django路由的两种方式,一种是定义到函数,另一种是调用到类。一把小项目就自己定义到函数就好了。但是当项目比较大的时候就需要将路由定义到类的身上,注意这里我们说的都是在views.py 中的类。 对于基类View,其暴露了一个as_view()的函数,该函数会对请求进一步做分发。下面两个就是这种方式路由的。 url(r'^Unit/(?P<pk>\w+)', UnitDetailView.as_view(), name='UnitDetail'), url(r'^Unit', UnitView.as_view(), name='Unit'), as_view() 是如何做分发的呢?它会调用一个dispatch函数对请求方式做个路由出去再调用到你真正的处理函数。总是很麻烦,还没来得及看代码。 不过这里有一个简化的另外一个类,继承的时候继承Generic. ...