
一种语言要使用到外部库(模块) 时必然会涉及到从哪里以及按何顺序加载依赖,就像 LD_LIBRARY_PATH, CLASSPATH 那样,Python 也有其默认的模块搜索顺序, 依序找到想要的模块即停止。Python 中
sys.path返回的列表包含了模块搜索的顺序,我们可以程序中修改该列表,或用PYTHONPATH环境变量前插路径,甚至是用.pth文件来附加路径。简单的,可以执行命令
python3 -c "import sys; print(str(sys.path).replace(',', '\n'))"来查看 python3 交互 shell 下的模块搜索路径,类似结果如下:[''
'/usr/lib/python36.zip'
'/usr/lib/python3.6'
'/usr/lib/python3.6/lib-dynload'
'/home/yanbin/.local/lib/python3.6/site-packages'
'/usr/local/lib/python3.6/dist-packages'
'/usr/lib/python3/dist-packages'
'/usr/lib/python3.6/dist-packages']注意,第一个元素是个空字符串,代表进入 python3 shell 时的当前目录。
如果在通过一个 py 脚本文件来打印
sys.path的话显示稍微有所差异。比如在目录/home/yanbin/Developers/下创建test.py文件,内容为 Read More
阅读到 Strings 中关于转换对象为字符串的内容,介绍了
repr函数,趁着还没有真正了解 Python 面向对象的生疏与热度,感性上理解一下repr与str这两个函数的区别。Python 的全局方法
repr和str会映射到对象的__repr__和__str__的方法调用,还有str(obj)时会调用哪个方法,以及print(obj)和调试 Python 代码时的对象显示会调用哪个方法呢?这就是本文想要印证的内容。恰如 Java 的
System.out.println(obj)或"hello" + obj都会调用 Java 对象的toString()方法,那么 Python 中是怎么一回事呢?来自某本 Python 入门书的解释
repr和str:repr: formal string representation of a Python objectstr: informal string representation of a Python object,或者说 printable string representation
首先
repr是 representation 的意思,一个是正式,另一个是非正式,看起来repr比str显得重要些。 Read More
两年前想摸摸 Python 的门道,简要记录了一篇 我的 Python 快速入门,当时只觉得那是一种与 C/Java 异样风格的编程语言,没领会到特别之处。如今对 Python 的感受就不一般了,因为是云服务,机器学习,人工知道大行其道的年代,所以更为急迫的想把它好好弄明白。
Python 3 说是设计的比 Python 2 要合理的多,所以没有保持向后兼容,现在初学 Python 对于选择哪个版本的 Python 时没有任何犹豫了,当然拣最新的 Python 3 学了。因此各种命令行工具都得用有 3 标记的,如
python3,pip3,pydoc3。编程语言特别是脚本语言,简单验证或入门最需要一个
REPL工具,这里不论大型项目时最好选择全功能型的 IDE,像 PyCharm 这样的重型武器。在安装 Python 3 后,它自带了两个,分别是python3和idle3(据说是 Integrated DeveLopment Environment 的缩写词, 可没见这么简陋的 IDE)Python
命令
python3进到控制台的 Python 交互界面,Python 标准的>>>提示符。没有语法高亮,没有自动缩进,唯一高级点的功能就是tab能对变量可以方法,属性的自动完成。 Read More
以实际 Java 项目中的单元测试 Mock 框架基本是 Mockito 2 了,因为它有一个十分流畅的 API。Mockito 2也为 JUnit 5 配上了 MockitoExtension, 所以 JUnit 5 下使用 Mockito 2 的关节也打通了。但在我们享受 Mockito 2 便利的同时,与 JMockit 相比局限性就很明显,因为 Mockito 2 是通过创建匿名子类来进行 Mock 的,所以任何子类对父类无法突破的方面它都存在。譬如,final 类, final 方法, 私有方法, 静态方法, 构造函数都是无法通过子类型进行重写的。所以除非特别需要,在 Mockito 2 无法胜任时都求助于 JMockit,JMockit 借助于 javaagent 取得了 JVM 的高控制权才得已为所欲为。
当 Mockito 来到了 2.1.0 版本,它也觉得不能对以上所有的限制置若罔闻, 首先带给我们的突破是它也可以 Mock final 类和 final 方法,虽然仍处于孵化器中,但毕竟是应用在单元测试中,能用就很不错了,只要以后不被拿走就行。这是官方对它的介绍 Mock the unmockable: opt-in mocking of final classes/methods
下面我亲自操作一遍,并给出更全方位的测试样例 Read More
我们在运行 docker 镜像时希望能用下面的命令向容器传递命令行参数docker run <image-name> <command> arg1 arg2
其实只有第一种形式,紧随镜像名后那个总是一个命令,其后才是参数。如果要向 docker 容器传递参数时,Dockerfile 该如何写,这就有必要稍稍了解一下 Dockerfile 中 CMD 和 ENTRYPOINT 这两个指令,并且它们有 exec 和 shell 两种格式的写法。详情请见上篇 Dockerfile 中命令的两种书写方式的区别。
docker run <image-name> arg1 arg2
对于一个 docker 镜像,我们可以这么来理解 ENTRYPOINT 与 CMD 的关系- 如果没有定义 ENTRYPOINT, CMD 将作为它的 ENTRYPOINT
- 定义了 ENTRYPOINT 的话,CMD 只为 ENTRYPOINT 提供参数
- CMD 可由
docker run <image>后的命令覆盖,同时覆盖参数
对于 #1 和 #2 更精致的理解是容器运行的最终入口由 ENTRYPOINT 和实际的 CMD 拼接而成。ENTRYPOINT 和 CMD 需转换为实际镜像中的 exec 格式来拼接,合并后的第一个元素是命令,其余是它的参数。 Read More
初识 Mockito 这个测试框架后,我们要使用 Mock 的属性创建一个被测试类实例时,大概会下面这么纯手工来打造。
假定类
UserService有一个属性UserDao userDao, 需要构造UserService实例时 Mock 内部状态UserDao userDao = Mockito.mock(UserDao.class);
UserService testMe = new UserService(userDao);如此,userDao 的行为就可以自由模拟了,这种纯手工方式都不需要给测试类添加
@RunWith(MockitoJunitRuner.class)
//或
MockitoAnnotations.initMocks(this);因为上面两句是给 Mockito 的注解使用的。
如果所有的 Mock 对象全部通过手工来创建,那就不容易体现出 Mockito 的优越性出来。因此对于被测试对象的创建,Mock 属性的注入应该让
@Mock和@InjectMocks这两个注解大显身手了。标注在实例变量上的
@Mock相当于是Mockito.mock(Class)创建了一个 Mock 对象,而@InjectMock标的实例会寻找到相应 Mock 属性想法构造出被测试类的实例。看下面的例子: Read More
Docker 镜像在未指定仓库时默认是从 Docker Hub 拉取的。如果需向 Docker Hub 推送镜像的话还可用docker login在交互中完成登陆 Docker Hub 的操作。docker login的命令格式是docker login [OPTIONS] [SERVER]
所以我们可以连接到任何的 Docker 镜像仓库,也可以是本机,但我们这里所要介绍的是如何推送镜像到 AWS 给我们提供的 Docker 镜像仓库(Amazon ECR - Amazon Elastic Container Registry)。每个帐号下都有自己独立的仓库,镜像推送到了 Amazon ECR 后我们能够很方便的在 ECS, Batch 服务中使用它,也可以从 ECR 拉取镜像到本地来。
首先我们来做一个运行 Spring Boot Web 的简单的 Docker 镜像,假定已用mvc pacakge生成了一个可独立运行的 jar 包java-webapp-0.0.1-SNAPSHOT.jar。该应用开启一个 Web 服务,访问 http://localhost:8080 显示一行字符串Hello World!
创建一个目录 aws-docker, 并把java-webapp-0.0.1-SNAPSHOT.jar移入该目录,在其下创建Dockerfile文件,文件目录结构如下:aws-docker
Read More
├── Dockerfile
└── java-webapp-0.0.1-SNAPSHOT.jar
在 Java 测试中使用 Mockito 有段时日了,以前只是想当然的认为 Mock 的对象属性值和方法返回值都是依据同样的规则。基本类型是 0, 0.0, 或 false, 对象类型都是 null, Mock 对象的默认返回值也应该是一样的。直到最近有一天,有一个返回
Optional<String>类型的方法,由于忘记对该方法打桩,意外的发现它返回的不是 null, 而Optional.empty(), 因此才意识到此处定有蹊跷。着实有必要用代码验证一下 Mockito 是怎么决定属性及方法的各种返回类型的默认值的。此次测试所用的 Mockito 版本是 mockito-core-2.12.0.
于是创建了下面一个类 MyClass 用于生成 Mock 对象,选取了一些典型的数据类型, 包括 int, Double, String, long[], Optional<String>, Collection<String>, Map<String, String>, 同时测试 Mock 对象默认的属性值与方法默认返回值。 Read More
本文发自于对平时编程习惯上的一些个人见解,还不至于牵扯到方法学的层面,尽管如此,也可能会招来许多不同的看法,只要是觉得经世致用就行。首先从耳熟能详的针对接口编程说起
是否总是针对接口编程
在初通软件设计时,针对接口编程这一理念似乎是宇宙真理(软件世界里并没有真理部),而且对它的解释是
具体类包含实现细节,而抽象类则只呈现概念
当然很在理,也很权威。
但针对接口的前提是什么呢?是在设计一个与外部系统交互的 API 情况下。比如要提供一个用户注册接口给外部,可以共同约定好接口为
void register(String username, String password) throws RegistrationException;
并且这个接口应该是稳固的,然后各自去实现或完成调用细节,即使实现未完成调用端也可以通过 Mock 来进行单元测试。
然而实际中对针对接口编程的理解很容易变为凡是非工具类,数据类都先声明一个接口挂单一实现类,类结构中就类似下面那样 Read More
一路阅读完第五章直接跳跃到第十章有关宏的内容,宏的录制和回放功能是多数编辑器都会提供,但我却基本不用这一功能。在 Vim 中宏比点号(.) 更有效的处理重复性操作,既然作为一个 Vimer, 以重复操作为耻,因而十分有必要对它加以了解和掌握的,又是一个一分钟上手需一辈子来掌握的东西。
1. 宏是录制在某个寄存器中,用 q{register}启动录制,例如qa, 然后执行一系操作,再次按q结束录制,第一次回放用@{register}, 如@a,以后多次执行上一次宏回放可用@@.也可以支持数字,如10@a, 或10@@.:reg a可查看寄存器a中宏的内容
2. 录制宏的一条金律是:确保每一条命令是可重复的。h,j,k,l, 没什么意义,而0e,A,I就是可重复的。当回放宏时遇到光标移动失败时, 如光标已在行首,宏中有h操作,那么后续的操作被放弃,根据visualbell配置可能有响声提示。宏的 motion 失败即放弃的特性让我们在重复执行宏时可以用一个足够大的数字,如200@@, 反正无副作用
3. 宏的序列执行与并发执行,当用5@a执行宏"a 0f.r)w~j, 其实是把宏放在一个队列里,往下跳行执行,其他任何一行执行失败,后续行将得不到更新。如果针对宏"a 0f.r)w~, 对选择的多行执行:'<,'>normal @a时效果就不一样了,它的意思是针对选择的多行单独执行宏,任何行的失败互不影响,所以它是并发执行的 Read More