Python(持续学习ing)

2018-01-22  本文已影响0人  _月光临海

长期置顶:

基础教程: http://www.cnblogs.com/dahu-daqing/p/6629577.html
基础教程: http://www.cnblogs.com/linhaifeng/p/7278389.html
爬虫教程: http://www.cnblogs.com/linhaifeng/p/8241221.html

2018-02-07

socket

简单 socket 例子(需要先启动服务端)

# Author:Freeman
import socket

client = socket.socket()  # 声明 socket 类型,同时生成socket连接对象,参数没填,但是有默认参数
client.connect(("localhost", 6969))

client.send(b"Hello World!")  #py3 不再允许字符串,需要 bytes 类型,bytes类型只能接受ASCII码,因此这里如果想要输入汉字:
# client.send("你好,世界!".encode("utf-8"))  # 接受时需要 decode 解码为 Unicode
data = client.recv(1024)  # 最多接收1024个字节
print("recv:", data)
client.close()
# Author:Freeman
import socket

server = socket.socket()
server.bind(("localhost", 6969))  # 绑定要监听的端口
server.listen()  # 监听
print("准备接收信息")
conn, addr = server.accept()  # 服务端需要等信息传进来
print(conn)
# conn:就是客户端连过来,而在服务器端为其生成的一个实例
# <socket.socket fd=484, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 6969)

print(addr)  # IP + 随机端口
print("接收信息")
data = conn.recv(1024)
print("recv:", data)
conn.send(data.upper())
server.close()

# 服务端

import socket

server = socket.socket()
server.bind(("localhost", 6969))  # 绑定要监听的端口
server.listen()  # 监听
print("准备接收信息")
while True:
    conn, addr = server.accept()  # 服务端需要等信息传进来
    while True:
        data = conn.recv(1024)
        if not data:
            print("客户端断开")
            break
        print("recv:", data.decode())
        conn.send(data.upper())  # upper() 转大写.将收到的数据转换为大写发送回客户端
server.close()
# 客户端
import socket

client = socket.socket()  # 声明 socket 类型,同时生成socket连接对象
client.connect(("localhost", 6969))

while True:
    msg = input(">>:").strip()
    # client.send(b"Hello World!")
    client.send(msg.encode("utf-8"))

    data = client.recv(1024)  # 接收1024个字节
    print("recv:", data.decode())
client.close()

2018-02-06

# Author:Gatling
class Person(object):
    # hahahaha
    '''描述信息'''

    def __init__(self, name):
        self.name = name
        # lalalala


print(Person.__doc__)       # 描述信息

反射


异常处理



2018-02-05

静态方法


类方法


属性方法

# Author:Gatling
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.__food = None

    @property
    def eat(self):
        print("%s is %s years old,eating %s" % (self.name, self.age, self.__food))

    @eat.setter  # 传参数
    def eat(self, food):
        print("set to food:", food)
        self.__food = food

    @eat.deleter
    def eat(self):
        del self.__food
        print("已删除")


Freeman = Person("Freeman", 18)
Freeman.eat
Freeman.eat = "包子"
Freeman.eat

del Freeman.eat
Freeman.eat

# Freeman is 18 years old,eating None
# set to food: 包子
# Freeman is 18 years old,eating 包子
# 已删除
# Traceback (most recent call last):
#   File "D:/ForPython/爬虫.py", line 29, in <module>
#     Freeman.eat
#   File "D:/ForPython/爬虫.py", line 10, in eat
#     print("%s is %s years old,eating %s" % (self.name, self.age, self.__food))
# AttributeError: 'Person' object has no attribute '_Person__food'

2018-02-04

面向对象

# 假设创建一个CS游戏:
# 有角色
# 射击
# 中枪
# 买枪

class Role(object):
    # 构造函数中的每个属性在新实例化一个对象的时候都会创建一份
    # 而方法只在 Role 中,不会随着新创建实例化对象而创建,每次调用的时候实际上是访问 Role 这个 class 中的方法
    def __init__(self, name, role, weapon, life_value=100, money=15000):
        # 构造函数
        # 在实例化时做一些类的初始化的工作
        # self 用于在实例化时传入'实例变量(静态属性)'(就是后面的 r1,r2)
        # self 的作用域就是 实例变量本身
        # Role(r1,..,..,..) 通过这样的方式告诉 Role 它的'实例变量'是 r1
        self.name = name
        self.role = role
        self.weapon = weapon
        # self.life_value = life_value
        self.__life_value = life_value  # 私有属性
        self.money = money

    def __del__(self):
        # 析构函数:在实例释放或销毁的时候自动执行的
        # 通常用于做一些收尾工作,如关闭数据库连接或之前打开的临时文件
        print("%s 触发析构函数" % self.name)

    def show_status(self):
        # 用于访问私有属性的函数
        # 私有属性在外面无法直接访问,因此只需要在内部定义一个可以在外部调用的方法,然后在外面调用即可
        print("通过定义 show_status() 访问到了私有属性 __life_value:%s" % self.__life_value)

    def shot(self):  # 动态属性
        # 为什么这里有个 self
        # 为了告诉这个函数,'谁'调用了这个方法
        # 这里面的'谁'就是'实例化名',也就是r1,r2
        # r1.shot() == Role.shot(r1)
        print("shooting...")

    def got_shot(self):
        print("ah...,I got shot...")

    def buy_gun(self, gun_name):
        print("%s just bought %s" % (self.name, gun_name))


r1 = Role('Alex', 'police', 'AK47')  # 实例化(初始化一个类,造了一个对象)

r2 = Role('Jack', 'terrorist', 'B22')
r1.buy_gun("Gatling")  # Alex just bought Gatling
# del r1    # 删除 r1
# 补充个垃圾回收机制和 __del__ 析构函数
# 进行这个操作后,r1 变量被删除,但 r1 所引用的内存还存在
# Python 通过垃圾回收机制定期循环内存,发现 r1 引用的内存地址还在,但 r1 已经没了
# 因此会认定 r1 内存地址已经没有用了,随即进行删除
# __del__ 析构函数就在此时触发
r2.buy_gun(("Gatling"))

# print(r1.__life_value)  # 报错
r1.show_status()

# Alex just bought Gatling
# Jack just bought Gatling
# 通过定义 show_status() 访问到了私有属性 __life_value:100
# Alex 触发析构函数
# Jack 触发析构函数

继承

class SchoolMember(object):
    members = 0  # 初始学校人数为0

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def tell(self):
        pass

    def enroll(self):
        '''注册'''
        SchoolMember.members += 1
        print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " % (
            self.name, SchoolMember.members))

    def __del__(self):
        '''析构方法'''
        print("\033[31;1mmember [%s] is dead!\033[0m" % self.name)


class Teacher(SchoolMember):
    def __init__(self, name, age, course, salary):
        # SchoolMember.__init__(self, name, age)
        super(Teacher, self).__init__(name, age)    # 与上面一样,在子类中重构父类的方法
        self.course = course
        self.salary = salary
        self.enroll()

    def teaching(self):
        '''讲课方法'''
        print("Teacher [%s] is teaching [%s] for class [%s]" % (self.name, self.course, 's12'))

    def tell(self):
        '''自我介绍方法'''
        msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' % (self.name, 'Oldboy', self.course)
        print(msg)


class Student(SchoolMember):
    def __init__(self, name, age, grade, sid):
        super(Student, self).__init__(name, age)
        self.grade = grade
        self.sid = sid
        self.enroll()

    def tell(self):
        '''自我介绍方法'''
        msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' % (self.name, self.grade, 'Oldboy')
        print(msg)


if __name__ == '__main__':
    t1 = Teacher("Alex", 22, 'Python', 20000)
    t2 = Teacher("TengLan", 29, 'Linux', 3000)

    s1 = Student("Qinghua", 24, "Python S12", 1483)
    s2 = Student("SanJiang", 26, "Python S12", 1484)

    t1.teaching()
    t2.teaching()
    t1.tell()
class A(object):    # class A:  经典类
    def __init__(self):
        print("A")


class B(A):
    def __init__(self):
        print("B")


class C(A):
    def __init__(self):
        print("C")

class D(B,C):
    pass

D()  # B
# Author:Gatling
class Animal(object):
    def __init__(self, name):  # Constructor of the class
        self.name = name

    def talk(self):  # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")


class Cat(Animal):
    def talk(self):
        print('%s: 喵喵喵!' % self.name)


class Dog(Animal):
    def talk(self):
        print('%s: 汪!汪!汪!' % self.name)


def func(obj):  # 一个接口,多种形态
    obj.talk()


c1 = Cat('小晴')
d1 = Dog('李磊')

func(c1)
func(d1)

2018-02-03

XML 模块

import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)

# 遍历xml文档
for child in root:
    print(child.tag, child.attrib)
    for i in child:
        print(i.tag, i.text)

# 只遍历year 节点
for node in root.iter('year'):
    print(node.tag, node.text)

import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml")
root = tree.getroot()
 
#修改
for node in root.iter('year'):    # 找到 year
    new_year = int(node.text) + 1
    node.text = str(new_year)
    node.set("updated","yes")    # 添加属性
 
tree.write("xmltest.xml")
 
 
#删除node
for country in root.findall('country'):      # 找到所有的 country
   rank = int(country.find('rank').text)
   if rank > 50:
     root.remove(country)    # 删除 node
 
tree.write('output.xml')
import xml.etree.ElementTree as ET
 
 
new_xml = ET.Element("namelist")    # Element 根节点
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})    # SubElement 子节点
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = '33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '19'
 
et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8",xml_declaration=True)  # xml_declaration 声明这是 xml 格式的
 
ET.dump(new_xml) # 打印生成的格式

ConfigParser 模块:解析配置文件


hashlib 模块:加密相关


hmac 模块:加密进阶版


tips


re 模块:正则

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
 
 
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 
# 结果
{'province': '3714', 'city': '81', 'birthday': '1993'}
>>> re.split("\d+","a1b22c333d4444e")
['a', 'b', 'c', 'd', 'e']

>>> re.split("\d","a1b22c333d4444e")
['a', 'b', '', 'c', '', '', 'd', '', '', '', 'e']

re.sub 匹配字符并替换

2018-02-02

标准库 - shutil 模块

# Author:Freeman
import shutil

# f1 = open('note', encoding="utf-8")  # 有这个文件
# f2 = open('note2', 'w', encoding='utf-8')  # 没有这个文件,创建一个
# shutil.copyfileobj(f1, f2)  # 把 f1 的内容复制一份到 f2

shutil.copyfile('note2', 'note3')  # 直接复制一个文件的副本(note3)
# shutil.copystat(src, dst)  # 拷贝:mode bits,atime,mtime,flags
# shutil.copy()  # 拷贝文件和权限
# shutil.copy2()  # 拷贝文件和状态信息
# shutil.copytree(原目录,目标目录) # 完整的拷贝目录
# shutil.rmtree()   # 删除目录
# shutil.move()  # 移动文件
# shutil.make_archive("压缩", 'zip', r'D:\ForPython\2018-1-30')  # 创建压缩包并返回路径

shelve 模块


2018-02-01

标准库 - random

import random
random.randint(1,10)    # 随机  [1,10] 的整数
random.randrange(1,10)    # 随机 (1,10) 的整数
random.choice(seq)  

标准库 - os

# Author:Freeman
import os

print(os.getcwd())  # 当前路径:D:\ForPython\2018-02-01
os.chdir(r"D:\ForPython\2018-02-01")  # 切换路径:命令行中为了避免转义,需要两个\\ ,也可以 r'D:\ForPython'
print(os.getcwd())  # D:\ForPython
print(os.curdir)  # 当前目录   .
print(os.pardir)  # 上一级目录   ..
os.makedirs(r'a\b\c')  # 递归创建目录(可以指定任意路径)
os.removedirs(r'a\b\c')  # 递归删除目录
# 删除目录(主要用于清理空目录):
# 1.检查c是否为空,是则删除c
# 2.检查b是否为空,是则删除b
# 3.检查a是否为空,是则删除a
os.mkdir(r"E:\abc")  # 创建目录(可以指定任意路径)
os.rmdir(r"E:\abc")  # 删除单个目录
print(os.listdir())  # 返回当前目录下的文件组成的一个 list(包括隐藏文件)
# os.rename(r'D:\ForPython\2018-02-01\level2_change', r'D:\ForPython\2018-1-31\level2')  # 把参数1的文件转移到参数2,支持改名
os.stat("os.py") # 获取文件 / 目录信息
os.environ # 查看环境变量
os.name # 当前系统名
os.path.abspath()
os.path.split(r"D:\a\b\c\d.txt")  # 返回:('D:\a\b\c','d.txt')  (不考虑文件是否存在)
os.path.basename(r"D:\a\b\c.txt")  # 返回:'c.txt'  (不考虑文件是否存在)
os.path.exists()  # 判断路径是否存在
os.path.isabs()  # 是否为绝对路径(Windows 以盘符开始,Linux以 / 开始)
os.path.isfile()  # 是否为一个文件
os.path.isdir()  # 是否为一个目录
os.path.join(r'C:',r'\a.txt')  # 'C:\a.txt'
os.path.getatime()  # 文件或目录的最后存取时间
os.path.getmtime()  # 文件或目录的最后修改时间
Name Windows Linux
路径斜杠 \ /
换行 \r\n \n
文件路径分隔符 ; :
Windows 系统下(Linux 对应表格)

标准库 - sys 模块


tips

折叠面板和自带命令行

2018-1-31

标准库 - time 模块

# time 具有的方法
time() -- return current time in seconds since the Epoch as a float
clock() -- return CPU time since process start as a float
sleep() -- delay for a number of seconds given as a float
gmtime() -- convert seconds since Epoch to UTC tuple
localtime() -- convert seconds since Epoch to local time tuple
asctime() -- convert time tuple to string
ctime() -- convert time in seconds to string
mktime() -- convert local time tuple to seconds since Epoch
strftime() -- convert time tuple to string according to format specification
strptime() -- parse string to time tuple according to format specification
tzset() -- change the local timezone
# Author:Freeman
import time

Epoch_time = time.time()
time_tuple = time.localtime(Epoch_time)
format_time = time.strftime("%Y-%m-%d %H:%M:%S", time_tuple)  # %Y 不是位置对应,%Y 放哪里都是年

print(Epoch_time)
print(time_tuple)
print(format_time)

# 1517414160.0117865
# time.struct_time(tm_year=2018, tm_mon=1, tm_mday=31, tm_hour=23, tm_min=56, tm_sec=0, tm_wday=2, tm_yday=31, tm_isdst=0)
# 2018-01-31 23:56:00
%a    本地(locale)简化星期名称    
%A    本地完整星期名称    
%b    本地简化月份名称    
%B    本地完整月份名称    
%c    本地相应的日期和时间表示    
%d    一个月中的第几天(01 - 31)    
%H    一天中的第几个小时(24小时制,00 - 23)    
%I    第几个小时(12小时制,01 - 12)    
%j    一年中的第几天(001 - 366)    
%m    月份(01 - 12)    
%M    分钟数(00 - 59)    
%p    本地am或者pm的相应符    一    
%S    秒(01 - 61)    二    
%U    一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。    三    
%w    一个星期中的第几天(0 - 6,0是星期天)    三    
%W    和%U基本相同,不同的是%W以星期一为一个星期的开始。    
%x    本地相应日期    
%X    本地相应时间    
%y    去掉世纪的年份(00 - 99)    
%Y    完整的年份    
%Z    时区的名字(如果不存在为空字符)    
%%    ‘%’字符

标准库 - datetime 模块

# Author:Freeman
import datetime

_now = datetime.datetime.now()
_future_day = datetime.datetime.now() + datetime.timedelta(3)
_ago_day = datetime.datetime.now() + datetime.timedelta(-3)
_future_hours = datetime.datetime.now() + datetime.timedelta(hours=3)
_future_minutes = datetime.datetime.now() + datetime.timedelta(minutes=15)
_ago_minutes = datetime.datetime.now() + datetime.timedelta(minutes=-15)

print(_now)                  # 2018-02-01 00:32:21.502319
print(_future_day)           # 2018-02-04 00:32:21.502319
print(_ago_day)              # 2018-01-29 00:32:21.502319
print(_future_hours)         # 2018-02-01 03:32:21.502319
print(_future_minutes)       # 2018-02-01 00:47:21.502319
print(_ago_minutes)          # 2018-02-01 00:17:21.502319

关于导入包

# grandpa.py
import level2

# level2 包内的 __init.py__
from . import level3

# level3  包内的 __init.py__
from . import son

# son.py 
text = "调用成功!"

# grandpa.py 中调用 son 中的方法
print(level2.level3.son.text)      # 调用成功!

tips

2018-1-30

模块

# 第一种导入
import module1,module2    # 导入多个模块
module1.func()            # 调用

# 第二种导入
from module import func        # 导入所有变量和函数(不建议,重名)
from module import func1,func2,func3
func()                          # 调用 不能 module1.func(),因为导入的是模块里的所有内容

# 第三种导入
from module import func as another_func      #  起个别名
another_func()                               # 调用

# 第四种导入
from . import func                 #  从当前目录下导入 func

2018-1-28

Python 内置方法

# Author:Freeman
list = [0, 1, 2, 3]
print(all(list))     # True
# Author:Freeman
a = bytes("abcde", encoding="utf-8")
b = bytearray("abcde", encoding="utf-8")
print(a.capitalize(), a)
print(b[0])  # ascii 码
b[0] = 98
print(b)

# b'Abcde' b'abcde'
# 97
# bytearray(b'bbcde')
# Author:Freeman

express = lambda n: n > 5
res = filter(express, range(10))
print(type(res))  # <class 'filter'>
for i in res:
    print(i)

# <class 'filter'>
# 6
# 7
# 8
# 9
# Author:Freeman

express = lambda n: n * n
res = map(express, range(5))
print(type(res))  # <class 'map'>
for i in res:
    print(i)

# <class 'map'>
# 0
# 1
# 4
# 9
# 16
# Author:Freeman

import functools

express = lambda x, y: x + y
res = functools.reduce(express, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  
# 计算过程 ((((((((0 + 1) + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9
print(res)

# 45
lambda n:3 if n<4 else n
# n 小于 4 就是 3,否则就是 n
# Author:Freeman
key = ["a", "b", "c", "d"]
val = [9, 5, 2, 7]

for i in zip(key, val):
    print(i)

# ('a', 9)
# ('b', 5)
# ('c', 2)
# ('d', 7)

序列化(dumps) / 反序列化(loads)

# Author:Freeman
import json

def sayhi():
    print("hello,", name)

jsonObj = {
    "name": "kaka",
    "age": "18",
    # "func":sayhi      # 会报错,不支持这种方式
}

f = open("yesterday", "r", encoding="utf-8")
# f.write(json.dumps(jsonObj))  # str
json.loads(f.read())      # dict
# Author:Freeman
import pickle


def sayhi(name):
    print("hello,", name)


pickleObj = {
    "name": "kaka",
    "age": "18",
    "func": sayhi
}

f = open("yesterday", "wb")
f.write(pickle.dumps(pickleObj))    # pickle.dump(pickleObj,f)  # 效果一样

以上代码存在于文件A,但在另一个文件B中去读 yesterday 这个文件会报错,因为 sayhi 这个函数只是存在于文件A之中,在文件B中是找不到 sayhi 的内存地址,除非在B中定义一个同名的 sayhi 函数


python 建议项目结构

Foo/
|-- bin/
|   |-- foo
|
|-- foo/
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
|
|-- docs/
|   |-- conf.py
|   |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README

简要解释一下:
# 
# bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
# foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。
# docs/: 存放一些文档。
# setup.py: 安装、部署、打包的脚本。
# requirements.txt: 存放软件依赖的外部Python包列表。
# README: 项目说明文件。
# 除此之外,有一些方案给出了更加多的内容。比如LICENSE.txt,ChangeLog.txt文件等,我没有列在这里,因为这些东西主要是项目开源的时候需要用到。如果你想写一个开源软件,目录该如何组织,可以参考这篇文章。

跨文件调用

# atm.py

# print(__file__) # 相对路径, pycharm 中显示的是绝对路径

import sys,os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath((__file__))))

# __file__ 代表当前文件
# os.path.abspath 绝对路径  D:\ForPython\atm\bin\atm.py
# os.path.dirname 当前文件所在的目录名,这里向上找了两次

sys.path.append(BASE_DIR)  # 添加环境变量
# sys.path 本身返回的是一个当前文件能访问到的路径组成的一个 list,
# 因此只要在这个 list 中添加一个新模块的路径,在当前文件中就可以 import 新模块
# 这里还有个问题,新插入的路径在最后面,如果在之前有重名的模块就不会调用到预期的模块,但由于是 list,可以不采取 append 而是 insert 之类的方法

from conf import settings
from core import main

main.info()

# 你已经成功调取到 main.py 的内容!
# main.py

def info():
    print("你已经成功调取到 main.py 的内容!")

2018-1-27

tips

生成器 generator

# Author:Freeman
generator = (i for i in range(10))
print(generator)
print(generator.__next__())
print(generator.__next__())

# <generator object <genexpr> at 0x000002E245B288E0>
# 0
# 1

列表生成式

# Author:Freeman
a = [i + 2 for i in range(10)]

print(a)
# [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# Author:Freeman

def func(*args):
    answer = "哈哈 %s" % args
    return answer


a = [func(i) for i in range(10)]
print(a)


生成器 + 异常处理

# Author:Freeman
def fib(max):
    n, a, b = 0, 0, 1

    while n < max:
        yield b        # 有 yield 的存在,fib 就已经是一个生成器了,而 b 就是生成器中的元素
        a, b = b, a + b
        n = n + 1
    return "----done----"        # 用于捕获错误


g = fib(5)
# 异常捕获
while True:
    try:
        # x = next(g)          # 在 3.0 中这句也好用
        x = g.__next__()
        print("g:", x)
    except StopIteration as e:      # 捕获 StopIteration 错误
        print("Generator return value:", e.value)
        break

# g: 1
# g: 1
# g: 2
# g: 3
# g: 5
# Generator return value: ----done----
# Author:Freeman
import time


def consumer(name):
    print("[%s]来吃包子了!" % name)
    while True:
        ab = yield
        print("[%s]包子来了,但是[%s]并没有吃到包子" % (ab, name))


c = consumer("大飞哥")
c.__next__()  # [大飞哥]来吃包子了!
c.__next__()  # [None]包子来了,但是[大飞哥]并没有吃到包子
c.__next__()  # [None]包子来了,但是[大飞哥]并没有吃到包子
c.send("韭菜馅")  # [韭菜馅]包子来了,但是[大飞哥]并没有吃到包子
c.send("面馅")  # [面馅]包子来了,但是[大飞哥]并没有吃到包子
c.__next__()  # [None]包子来了,但是[大飞哥]并没有吃到包子

# Author:Freeman
import time


def consumer(name):
    print("[%s]来吃包子了!" % name)
    while True:
        ab = yield
        print("[%s]包子来了,但是[%s]并没有吃到包子" % (ab, name))


list = ["韭菜馅",  "面馅"]


def producer(name):
    c = consumer("A")
    c2 = consumer("B")
    c.__next__()
    c2.__next__()
    print("[%s]开始准备做包子啦!" % name)
    for i, item in enumerate(list):
        time.sleep(1)
        print("%s做了两个包子!"%name)
        c.send(item)
        c2.send(item)


producer("大帅哥")

# [A]来吃包子了!                          # consumer
# [B]来吃包子了!                          # consumer
# [大帅哥]开始准备做包子啦!            # producer
# [大帅哥]做了两个包子!                # producer
# [韭菜馅]包子来了,但是[A]并没有吃到包子    # consumer
# [韭菜馅]包子来了,但是[B]并没有吃到包子    # consumer
# [大帅哥]做了两个包子!                # producer
# [面馅]包子来了,但是[A]并没有吃到包子      # consumer
# [面馅]包子来了,但是[B]并没有吃到包子      # consumer

迭代器


装饰器

# Author:Freeman
import time

user, passwd = "kaka", "123"


def auth(auth_type):
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            if auth_type == "local":
                username = input("Username:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print("\033[32;1mUser has passed authentication\033[0m")
                    return func(*args, **kwargs)
                else:
                    exit("\033[31;1mInvalid username or password\033[0m")
            elif auth_type == "ldap":
                print("搞毛线?")

        return wrapper

    return outer_wrapper


def index():
    print("welcome to index page")


@auth(auth_type="local")
def home():
    print("welcome to home page")
    return "from home"


@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs page")

# index()
# print(home())
home()
# bbs()


2018-1-26

装饰器

# Author:Freeman
import time


def timer(func):
    def deco():
        start_time = time.time()
        func()
        end_time = time.time()
        print("func run time is %s" % (end_time - start_time))

    return deco


@timer      # 装饰器,之后直接调用 test1 就是携带装饰器的调用,装饰器作用于紧邻它下面的第一个函数
def test1():
    time.sleep(2)
    print("this is test1 func")

test1()
# timer(test1)()    # 如果不用装饰器,也可以这么写
# Author:Freeman
import time


def timer(func):
    def deco(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print("func run time is %s" % (end_time - start_time))

    return deco


@timer
def test1(*args, **kwargs):
    time.sleep(2)
    print("this is test1 func:", *args, **kwargs)


# timer(test1)()
# test1 = timer(test1)  # 不要考虑那些乱七八糟的,timer 执行返回 deco 地址,test1 就是 deco 地址,再进一步说,调用 test1 就是调用 deco 
test1("kaka", {"dict_key": 5})
# Author:Freeman
import time

user, passwd = "kaka", "123"


def auth(func):
    def wrapper(*args, **kwargs):
        username = input("Username:").strip()
        password = input("Password:").strip()
        if user == username and passwd == password:
            print("\033[32;1mUser has passed authentication\033[0m")
            func(*args, **kwargs)
        else:
            exit("\033[31;1mInvalid username or password\033[0m")

    return wrapper


def index():
    print("welcome to index page")


@auth
def home():
    print("welcome to home page")
    return "from home"        # 为什么这行没有返回?打印结果中的 None 是哪来的?


@auth
def bbs():
    print("welcome to bbs page")


index()
print(home())
bbs()

# welcome to index page
# Username:kaka
# Password:123
# User has passed authentication
# welcome to home page
# None      # 这是什么鬼?from home 呢?
# Username:

# 解释:
# 如上个例子所言,调用 home 就等于调用 wrapper
# 然而 home 有返回值,装饰器中 wrapper 中的 home() 也的确进行了调用并返回了 from home,但是 wrapper 没有 return
# 可以理解为 wrapper 中已经包含了 home 的返回值 from home ,但是 wrapper 没有把 这个 from home 的结果 return 出来
# 没有 return 语句的函数默认返回值为 None
# 注意:return wrapper 是 auth 的返回值,不是 wrapper 的

2018-1-25

tips

装饰器


2018-1-24

递归


函数

# Author:Freeman
def func(x, y, z=3):
    print(x)
    print(y)
    print(z)

func(2, 1, "kk")
# 输出 2,1,kk
# Author:Freeman
def func(*args):
    print(args)
    print(args[1])
    print(len(args))


func(2, 1, "kk")
# (2, 1, 'kk')
# 1
# 3
# Author:Freeman
def dict(name, age=12, *args):
    print(name)
    print(age)
    print(args)


dict(*["lky", "222", "gogogo"])
# lky
# 222
# ('gogogo',)
# Author:Freeman
def dict(**kwargs):
    print(kwargs)

dict(name="xxx", age="123", salary="没有")                  # 第一种
dict(**{"name" : "xxx", "age" : "123", "salary" : "没有"})  # 第二种
# {'name': 'xxx', 'age': '123', 'salary': '没有'}    
# {'name': 'xxx', 'age': '123', 'salary': '没有'}

**kwargs 参数组往后放:当关键字参数合法时,不会被当做字典参数

# Author:Freeman
def dict(name, age=12, **kwargs):
    print(name)
    print(age)
    print(kwargs)

dict(name="lky",age="222",key="gogogo")
# lky
# 222
# {'key': 'gogogo'}
# Author:Freeman
abc = 12

def change(param=3):
    global abc  # 这里不能写赋值
    abc = 11
    print(abc)  # 这里不能写赋值

change()
# 11

2018-1-23

编程方式


函数

# Author:Freeman
def func(x, y):
    print(x)
    print(y)

# func(1, 2)
func(y=1, x=2)

输出时间

# Author:Freeman
import time

rule = "%Y-%m-%d %X"
time = time.strftime(rule)
print(time)
# 输出  2018-01-23 23:08:23

2018-1-22

打印系统默认编码


ASCII Unicode utf-8 的区别


with

# Author:Freeman
import sys

with open("yesterday", "r", encoding="utf-8") as f, \
        open("yesterday2", "r", encoding="utf-8") as f2:
    for i in f:
        print(i.strip())

tips


sys.argv

# Author:Freeman
import sys

item = sys.argv
print(item)
print(item[0])
print(item[1])
print(item[2:])
需要在命令行下
# Author:Freeman
import sys

f = open("yesterday", "r+", encoding="utf-8")

old_str = sys.argv[1]
new_str = sys.argv[2]

for line in f:
    if old_str in line:
        line = line.replace(old_str, new_str)
        print(line)
yesterday 文件的内容
命令行中执行结果

之前的

快捷键

input()

# Author:Liu
import getpass

_username = "lky"
_password = "123"
username = input("name:")
password = getpass.getpass("password:")

if _username == username and _password == password:
    print("Welcome {name} login".format(name=username))    # 字符串连接
else:
    print("Invalid username or password")

循环 判断 跳出循环

# Author:Liu

age_of_oldboy = 56

while True:
    guess_age = int(input("guess age:"))
    if guess_age == age_of_oldboy:
        print("yes ,you got it.")
        break
    elif guess_age > age_of_oldboy:
        print("think smaller...")
    else:
        print("think bigger!")

range()

# Author:Liu
for i in range(1, 10, 3):
    print(i)      # 1,4,7

打断点

image.png

模块(库)

# 一些常用的 os 方法
# Author:Liu
import os

# cmd_res = os.system("dir")  # 执行命令,无法保存结果
# cmd_res = os.popen("dir")   # 内存对象地址
# cmd_res = os.popen("dir").read()   # 读取地址
os.mkdir("new_dir_by_python")      # 创建目录
print("-->", cmd_res)

.pyc 是什么?


数据类型


三元运算

result = 值1 if 条件1 else 条件2

十六进制表示法


编码和解码


切片

# Author:Liu
names = ["a", "b", "c", "d"]
print(names[0])
print(names[1:2])
print(names[1:])
print(names[-2:])
names.insert[1,"abc"]      # 插入
names[2] = "aaaa"          # 替换
del names[1]               # 删除    也可以删除变量
names["c"]                 # 删除
切片
# Author:Liu
import copy

names = ["name", ["saving"]]
# 浅copy的三种方式
names2 = copy.copy(names)
names2 = names[:]
names2 = list(names)
# 浅copy的用途 —— 联合账号
names[0] = "husband"
names2[0] = "wife"
names[1][0] = 5000

print(names)        #['husband', [5000]]
print(names2)       #['wife', [5000]]

# Author:Liu
import copy
# 深copy
names = ["a", "b", "b", [1, 2], "c", "d"]
names2 = copy.deepcopy(names)
names2[3][1] = "bbbbb"
print(names[3][1])

元祖(只读列表)


.isdigital()


enumerate()

字符串操作,注意,是字符串的方法

# Author:Liu
name = "123"
print(name.center(40, "-"))
# ------------------123-------------------
# Author:Liu
name = "My name is {name},I'm {age} years old"
print(name.format(name="kaka", age='2222'))
print(name.format_map({"name":"Dictionary","age":"122"}))
# My name is kaka,I'm 2222 years old
# My name is Dictionary,I'm 122 years old
p = str.maketrans("abcd", "1234")  # 重复的话以最后为准,数量必须一样
print("abcd".translate(p))
# 输出:1234

字典 Dictionary

# Author:Liu
info = {
    "aaa": "111",
    "bbb": "222",
    "ccc": "333",
    "ddd": {
        "ddd-1": 1,
        "ddd-2": 2,
        "ddd-3": 3
    }
}
print(info.items())
# 输出:dict_items([('aaa', '111'), ('bbb', '222'), ('ccc', '333'), ('ddd', {'ddd-1': 1, 'ddd-2': 2, 'ddd-3': 3})])

9.fromkeys():初始化一个 dict

test = dict.fromkeys([6, 7,"link"], {"key": "value"})
test["link"]["key"] = "new_value"
print(test)
# 输出 {6: {'key': 'new_value'}, 7: {'key': 'new_value'}, 'link': {'key': 'new_value'}}
# 注:有引用问题

pass


集合及其方法

# Author:Freeman
list_1 = [1, 4, 5, 7, 3, 6, 7, 9]
list_1 = set(list_1)
print(set(list_1), type(list_1))
# 输出:{1, 3, 4, 5, 6, 7, 9} <class 'set'>

文件操作

data = open("yesterday",encoding="utf-8").read()
print(data)
 f = open(xxx,encoding="utf-8") # 文件句柄,这里指向文件的内存地址
# Author:Freeman
f = open("yesterday","r", encoding="utf-8")  # r 读 w 写,不写为默认 r
data = f.read()
print(data) # print(f.read())  不报错但也不出结果
for line in f:
    print(line.strip())
# Author:Freeman
import sys, time

for i in range(10):
    sys.stdout.write("#")
    sys.stdout.flush()
    time.sleep(.5)
上一篇下一篇

猜你喜欢

热点阅读