Python 基础的笔记

大学时候就写了不少 Python 代码。最近又用到了,复习一下。 参考资料Python 之旅 - 极客学院

背景知识

Python2 的默认编码是 ascii,Python3 的默认编码是 utf-8

输入输出

Python2 提供了 inputraw_inputprint 等用于输入输出,但在 Python3 中发生了一些改变,raw_input 已经没有了,input 的用法发生了变化,print 也从原来的语句变成了一个函数。

name = input('please input your name: ')

使用 input 的时候,如果输入的是字符串,必须使用引号把它们括起来;如果输入的是数值类型,则返回的也是数值类型;如果输入的是表达式,会对表达式进行运算。

print('%10.3f' %pi)     # 字段宽度 10,精度 3
print('%010.3f' % pi)    # 用 0 填充空白
print('%+f' % pi)        # 显示正负号
print('%10.3f' %pi) ,     # 不换行输出,逗号,中间填充空格

Python3 中使用 print 必须加括号。

print(i, end='')    # 加上一个 end 参数 不换行输出

数据类型

定义

# 列表[] 值,可以对它进行随意修改。 
numbers = [1, 2, 3, 4, 5, 5, 7, 8]
words = ['hello', 'world', 'you', 'me', 'he']
numbers[1]
words[2]

# 元组() 元组是一种不可变序列,不能赋值
a = (1, 2, 3)   
a[2] 

# 字符串'' 和元组一样,不可变不能赋值:
s = 'hello, '
s[3]

# 字典{} 键值对 
d1 = {'name': 'ethan', 'age': 20}
d1['age']

# 集合{} 键,无值
s1 = {'a', 'b', 'c', 'a', 'd', 'b'}

列表

列表常用方法:

  • index
  • count
  • append
  • extend
  • insert
  • pop
  • remove
  • reverse
  • sort

字符串常用方法:

  • find
  • split
  • join
  • strip
  • replace
  • translate
  • lower/upper

字典常用方法

  • clear
  • copy
  • get
  • setdefault
  • update
  • pop
  • popitem
  • keys/iterkeys
  • values/itervalues
  • items/iteritems
  • fromkeys

函数

  • 参数组合在使用的时候是有顺序的,依次是必选参数、默认参数、可变参数和关键字参数。
  • *args**kwargs 是 Python 的惯用写法。
def func(x, y, z=0, *args, **kwargs):
    print 'x =', x
    print 'y =', y
    print 'z =', z
    print 'args =', args
    print 'kwargs =', kwargs

语句

if else

num = 5     
if num == 3:            # 判断num的值
    print 'boss'    
elif num < 0:           # 值小于零时输出
    print 'error'
else:
    print 'roadman'     # 条件均不成立时输出

while

count = 0
while (count < 9):
   print 'The count is:', count
   count = count + 1
 
print "Good bye!"

for

for iterating_var in sequence: 
	statements(s)

for (index,iterating_var) in sequence: 
	statements(s)

# 序列索引
fruits = ['banana', 'apple',  'mango']
for index in range(len(fruits)):
   print '当前水果 :', fruits[index]
 
print "Good bye!"

# 输出 2 到 100 的质数
prime = []
for num in range(2,100):  # 迭代 2 到 100 之间的数字
   for i in range(2,num): # 根据因子迭代
      if num%i == 0:      # 确定第一个因子
         break            # 跳出当前循环
   else:                  # 循环的 else 部分
      prime.append(num)
print prime

try…catch…

try:
     Normal execution block
except A:
     Exception A handle
except B:
     Exception B handle
except:
     Other exception handle
else:
     if no exception,get here
finally:
     print("finally")

参考资料


Python 类的笔记

一些笔记而已。

面向对象

  • 类是具有相同属性方法的一组对象的集合,实例是一个个具体的对象。
  • 方法是与实例绑定的函数。
  • 获取对象信息可使用下面方法:
    • type(obj):来获取对象的相应类型;
    • isinstance(obj, type):判断对象是否为指定的 type 类型的实例;
    • hasattr(obj, attr):判断对象是否具有指定属性/方法;
    • getattr(obj, attr[, default]) 获取属性/方法的值, 要是没有对应的属性则返回 default 值(前提是设置了 default),否则会抛出 AttributeError 异常;
    • setattr(obj, attr, value):设定该属性/方法的值,类似于 obj.attr=value;
    • dir(obj):可以获取相应对象的所有属性和方法名的列表:
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

Python类简介

类的私有属性:

__private_attrs  两个下划线开头,声明该属性为私有,使用时 self.__private_attrs

类的方法

使用def关键字可以为类定义一个方法,类方法必须包含参数self,且为第一个参数

私有的类方法

__private_method 两个下划线开头,声明该方法为私有方法,调用时 slef.__private_methods

类的专有方法(魔法方法):

__init__  构造函数,在生成对象时调用
__del__   析构函数,释放对象时使用
__repr__ 打印,转换
__setitem__按照索引赋值
__getitem__按照索引获取值

__len__获得长度
__cmp__比较运算
__call__函数调用

__add__加运算
__sub__减运算
__mul__乘运算
__div__除运算
__mod__求余运算
__pow__称方
  • __new____init__ 之前被调用,用来创建实例。
  • __str__ 是用 print 和 str 显示的结果,__repr__ 是直接显示的结果。
  • __getitem__ 用类似 obj[key] 的方式对对象进行取值
  • __getattr__ 用于获取不存在的属性 obj.attr
  • __call__ 使得可以对实例进行调用

使用 dir(obj) 可以获取相应对象的所有属性和方法名的列表,以下是个例子

['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'age',
 'greet',
 'name']

示例

class People:
    name = ''
    age = 0
    __weight = 0

    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s is speaking: I am %d years old" %(self.name,self.age))

p = People('tom',10,30)
p.speak()

继承和多态

class Man(People):
    def speak(self):
        print 'hello.., I am %s. ' %self.name

类方法和静态方法

class A(object):
	@classmethod
	def class_foo(cls)
	
	@staticmethod
	def static_foo():

类方法参数是 cls,静态方法没有 self 参数

slots 魔法

限定允许动态绑定的属性,减少因为动态绑定带来的内存消耗。

  • __slots__ 设置的属性仅对当前类有效,对继承的子类不起效,除非子类也定义了 slots,这样,子类允许定义的属性就是自身的 slots 加上父类的 slots。

@property

把方法『变成』了属性。如果不设定 setter,就是只读属性。

class Exam(object):
    def __init__(self, score):
        self._score = score

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, val):
        if val < 0:
            self._score = 0
        elif val > 100:
            self._score = 100
        else:
            self._score = val

super

super 的一个最常见用法是在子类中调用父类的初始化方法。你可以认为 super 调用了父类的方法,实际上和父类没有什么关系。

对于我们定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表它代表了类继承的顺序,更加具体的内容查看这里http://wiki.jikexueyuan.com/project/explore-python/Class/super.html

元类 metaclass

  • 在 Python 中,类也是一个对象。
  • 类创建实例,元类创建类。
  • 元类主要做了三件事:
    • 拦截类的创建
    • 修改类的定义
    • 返回修改后的类
  • 当你创建类时,解释器会调用元类来生成它,定义一个继承自 object 的普通类意味着调用 type 来创建它。

更加具体的内容查看这里http://wiki.jikexueyuan.com/project/explore-python/Class/metaclass.html


Python Selenium 节点的相关操作

获取 html

element.get_attribute('innerHTML')
element.get_attribute('outerHTML')

获取内容

element.text

获取属性

element.get_attribute('data-original-title') 

是否存在

def isElementExist(self, element, node=''):
    flag = True
	if node == '':
		node = self.driver

    try:
        node.find_element_by_xpath(element)
        return flag
    except:
        flag = False
	
	return flag

模糊匹配属性

使用 XPath:

//a[contains(@prop,'Foo')]

参考资料


Linux 命令之 htop

top是linux下常用的监控程序,然而已经很多年没有更新了。htop相当于其加强版,颜色显示不同参数,且支持鼠标操作。这篇文章做一个简单的介绍。

安装

sudo apt-get install htop

进程信息

PID:进程标志号,是非零正整数
USER:进程所有者的用户名
PR:进程的优先级别
NI:进程的优先级别数值
VIRT:进程占用的虚拟内存值
RES:进程占用的物理内存值
SHR:进程使用的共享内存值
S:进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数
%CPU:该进程占用的CPU使用率
%MEM:该进程占用的物理内存和总内存的百分比
TIME+:该进程启动后占用的总的CPU时间
COMMAND:进程启动的启动命令名称

基本操作

F1 : 查看htop使用说明
F2 : 设置
F3 : 搜索进程
F4 : 过滤器,按关键字搜索
F5 : 显示树形结构
F6 : 选择排序方式
F7 : 减少nice值,这样就可以提高对应进程的优先级
F8 : 增加nice值,这样可以降低对应进程的优先级
F9 : 杀掉选中的进程
F10 : 退出htop

/ : 搜索字符
h : 显示帮助
l :显示进程打开的文件: 如果安装了lsof,按此键可以显示进程所打开的文件
u :显示所有用户,并可以选择某一特定用户的进程
s : 将调用strace追踪进程的系统调用
t : 显示树形结构

H :显示/隐藏用户线程
I :倒转排序顺序
K :显示/隐藏内核线程    
M :按内存占用排序
P :按CPU排序    
T :按运行时间排序

上下键或PgUP, PgDn : 移动选中进程
左右键或Home, End : 移动列表    
Space(空格) : 标记/取消标记一个进程。命令可以作用于多个进程,例如 "kill",将应用于所有已标记的进程

参数说明

htop –d 数据刷新时间 
htop –u aurain 显示用户aurain的所属进程 
M 按Memory 使用排序 
P 按CPU 使用排序 
T 按Time+ 使用排序 
F3 按进程名搜索 
直接输入数字 光标将定位于该PID的进程 
q 退出

简单的 v2ex 自动签到程序 —— 基于 Python Selenium

最近看了点 Selenium 的东西,随手写的一个demo,使用 Chrome 内核,模拟用户每日签到的动作,比较简单的。

# -*- coding:utf-8 -*- 

from selenium import webdriver
import time
import random
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains

username = "" 
password = "" 
driver = webdriver.Chrome()
baseUrl = 'https://www.v2ex.com' 
loginUrl = '/signin' 
daliyUrl = '/mission/daily'   

driver.get(baseUrl)
print 'Enter ' + driver.title

time.sleep(random.randint(4,9))
driver.get(baseUrl + loginUrl)

print 'Enter ' + driver.title

tr_elems = driver.find_element_by_id('Main').find_element_by_tag_name('form').find_elements_by_tag_name('tr')

for index, tr_elem in enumerate(tr_elems):
    if index == 0:
        td_elems = tr_elem.find_elements_by_tag_name('td')
        td_name = td_elems[0]
        td_input = td_elems[1].find_element_by_tag_name('input')
        ActionChains(driver).move_to_element(td_input).perform()

        print td_name.text
        td_input.send_keys(username)
    if index == 1:
        td_elems = tr_elem.find_elements_by_tag_name('td')
        td_name = td_elems[0]
        td_input = td_elems[1].find_element_by_tag_name('input')
        ActionChains(driver).move_to_element(td_input).perform()

        print td_name.text
        td_input.send_keys(password)
    if index == 2:
        td_elems = tr_elem.find_elements_by_tag_name('td')
        td_input = td_elems[1].find_elements_by_tag_name('input')[1]
        ActionChains(driver).move_to_element(td_input).perform()

        td_input.click()

# 登录成功就切到新页面 
try:
    mainPage = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.ID, "Rightbar"))
    )
except:
    print "login error" else:
    print 'login ok. Enter ' + driver.title

try:
    dailyButton = WebDriverWait(driver, 1).until(
        EC.presence_of_element_located((By.XPATH, "//a[contains(text(),'领取今日的登录奖励')]"))
    )
except:
    print "no daily corn" else:
    dailyButton = driver.find_element_by_xpath("//a[contains(text(),'领取今日的登录奖励')]")
    ActionChains(driver).move_to_element(dailyButton).click(dailyButton).perform()

time.sleep(random.randint(4,9))
print 'Enter ' + driver.title

try:
    dailyButton = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.XPATH, "//input[contains(@value,'领取')]"))
    )
except:
    print "no daily corn"   
else:
    print "get daily corn"
  	dailyButton = driver.find_element_by_xpath("//input[contains(@value,'领取')]")
    ActionChains(driver).move_to_element(dailyButton).click(dailyButton).perform()

参考资料


Python 生成随机数

# coding:utf-8
import time
import random

time.sleep(random.randint(4,9))

这里我用了 random 模块的 randint() 函数来生成随机数,每次执行后都返回不同的数字(4到 9)。

函数的语法为:

random.randint(a,b)

函数返回数字 N ,N 为 a 到 b 之间的数字(a <= N <= b),包含 a 和 b。

参考资料