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']

示例

```python 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))

Django 入门笔记

记录一下步骤。我是按照网上的这个教程——Django 博客教程 进行学习的。对应的 github 地址戳这里

这一篇是精简后的备忘,中间夹杂一些个人的看法。

开发环境准备

我的开发环境是 MacOS Sierra,Python 2.7.13 (64 位),Django 1.10.6。

Virtualenv 会从系统的 Python 环境中克隆一个全新的 Python 环境出来,这个环境独立于原来的 Python 环境。

cd ~ pip install virtualenv

新建虚拟环境

virtualenv vens

激活虚拟环境

source vens/bin/activate

开始项目

cd workspace
django-admin startproject blogproject

生成项目的内部的文件结构如下:

blogproject\
    manage.py
    blogproject\
        __init__.py
        settings.py
        urls.py
        wsgi.py

blogproject/blogproject/settings.pyLANGUAGE_CODE 的值改为 zh-hansTIME_ZONE 的值改为 Asia/Shanghai

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

测试运行

python manage.py runserver

# 自定义端口和监听地址
python manage.py runserver 0.0.0.0:12345

Django 的规范希望我们把自己编写的代码组织到应用(Application)里,一个应用只提供一种功能。所以在 blogproject 项目中我先生成一个 blog 的应用。

cd blogproject
python manage.py startapp blog

生成 app 的文件结构如下:

blog\
    __init__.py
    admin.py
    apps.py
    migrations\
        __init__.py
    models.py
    tests.py
    views.py

新应用注册

然后在 setting 里注册新建的这个应用,找到 INSTALLED_APPS 设置项,将 blog 应用添加进去。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog', # 注册 blog 应用
]

模型 model

django 的 model.py 既包含数据库中的字段,也包含逻辑。同时会根据 model 字段自动生成 migration。

blog/models.py

from django.db import models
from django.contrib.auth.models import User

class Category(models.Model):
    name = models.CharField(max_length=100)

class Tag(models.Model):
    name = models.CharField(max_length=100)

class Post(models.Model):
    title = models.CharField(max_length=70)
    body = models.TextField()
    created_time = models.DateTimeField()
    modified_time = models.DateTimeField()
    excerpt = models.CharField(max_length=200, blank=True)
    category = models.ForeignKey(Category)
    tags = models.ManyToManyField(Tag, blank=True)
    author = models.ForeignKey(User)

生成迁移

python manage.py makemigrations
python manage.py migrate

可以运行下面的命令看看 Django 究竟为我们做了什么:

python manage.py sqlmigrate blog 0001

直接添加数据

python manage.py createsuperuser

Username (leave blank to use 'xxx'):  admin
Email address:  admin@example.com
Warning: Password input may be echoed.
Password:  ******
Warning: Password input may be echoed.
Password (again):  ******
Superuser created successfully.

模型注册

blog/admin.py

from django.contrib import admin
from .models import Post, Category, Tag

admin.site.register(Post)
admin.site.register(Category)
admin.site.register(Tag)

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。


1 2 37 38 39 40 41 77 78