diff --git a/README.md b/README.md index 3fd48e9..745e4be 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ # learn-python -本人边学习Python3,边把一些小脚本(自己写的和网上找的)经过本机测试后然后同步到github上,供初学者下载研究,欢迎fork,也欢迎提交新的Python小脚本,特别是一些有趣好玩的小程序! +本人边学习Python3,边把一些小脚本(自己写的和网上找的)经过本机测试后然后同步到github上,供初学者下载研究,欢迎fork,也欢迎提交新的Python小脚本,特别是一些有趣好玩的小程序!有什么问题可以通过Issues讨论,喜欢的话点Star或分享给别人哦! -http://www.tantengvip.com/category/develop/python3/ +学习Python3记录博客: +http://blog.tanteng.me/category/develop/python3/ + +注:IDE是PyCharm4.5,Python版本是3.4.3 + +欢迎大家提交好的学习Python3的脚本,我会合并进来! diff --git a/args_kwargs.py b/args_kwargs.py index 6b98e48..4095ca7 100644 --- a/args_kwargs.py +++ b/args_kwargs.py @@ -1,5 +1,25 @@ +# encoding:utf-8 + +# -*- Python3可变参数 -*- + +import webbrowser + def alias(*args, **kwargs): print('args=', args) print('kwargs=', kwargs) + return alias(3, 23, 3, 3,a='hello',b=3,c='C') + +""" +输出: +args= (3, 23, 3, 3) +kwargs= {'b': 3, 'c': 'C', 'a': 'hello'} + +小结: +*args表示任何多个无名参数,它是一个tuple +**kwargs表示关键字参数,它是一个dict +""" + +# 具体参考资料 +webbrowser.open('http://www.tantengvip.com/2015/07/python-args-kwargs/', 1) diff --git a/args_unpacking.py b/args_unpacking.py new file mode 100644 index 0000000..6c83b07 --- /dev/null +++ b/args_unpacking.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +# 使用tupple或dict传参的技巧 + +def product(a, b): + print(str(a) + '*' + str(b)) + return a * b + +argument_tuple = (1, 1) +argument_dict = {'a': 1, 'b': 1} + +print(product(*argument_tuple)) # 这里用*解析tupple类型的变量作为product的参数 +print(product(**{'b':4,'a':3})) # 这里用**解析dict类型的变量作为product的参数 diff --git a/binary_search.py b/binary_search.py new file mode 100644 index 0000000..ea2cfa8 --- /dev/null +++ b/binary_search.py @@ -0,0 +1,23 @@ +# encoding:utf-8 + +# -*- Python二分查找算法 -*- +import sys + +def binarySearch(l, t): + low, high = 0, len(l) - 1 + while low < high: + print(low, high) + mid = int((low + high) / 2) + if l[mid]> t: + high = mid + elif l[mid] < t: + low = mid + 1 + else: + return mid + return False + +if __name__ == '__main__': + l = [1, 4, 12, 45, 66, 99, 120, 444] + print(binarySearch(l, 12)) + print(binarySearch(l, 1)) + print(binarySearch(l, 13)) \ No newline at end of file diff --git a/check_ip.py b/check_ip.py new file mode 100644 index 0000000..321e82c --- /dev/null +++ b/check_ip.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +#coding:utf-8 + +import urllib.request +import re +import sys + +def ISIP(s): + return len([i for i in s.split('.') if (0<= int(i)<= 255)])== 4 + +def URL(ip): + uip = urllib.request.urlopen('http://wap.ip138.com/ip.asp?ip='+ip) + fip = uip.read() + rip = re.compile("
查询结果:(.*)
") + result = rip.findall(fip) + print("%s\t %s" % (ip, result[0])) + + +def DO(domain): + url = urllib.request.urlopen('http://wap.ip138.com/ip.asp?ip='+domain) + f = url.read().decode('utf-8') + r = re.compile('
查询结果:(.*)
') + result = r.findall(f) + #print type(result) + for i in result: + print("%s %s %s" % (domain, i[0], i[1])) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("请输入IP地址或者域名 (例如:192.168.1.1 / www.baidu.com)") + sys.exit() + INPUT=sys.argv[1] + if not re.findall('(\d{1,3}\.){3}\d{1,3}',INPUT): + if re.findall('(\w+\.)?(\w+)(\.\D+){1,2}',INPUT) : + DOMAIN=INPUT + DO(DOMAIN) + else: + print("输入的IP地址和域名格式不对!") + else: + if ISIP(INPUT) : + IPADDRESS=INPUT + URL(IPADDRESS) + else: + print("IP 地址不合法,请重新输入!") diff --git a/checkfile.py b/checkfile.py new file mode 100644 index 0000000..ef6a3db --- /dev/null +++ b/checkfile.py @@ -0,0 +1,30 @@ +import sys # Import the Modules +import os # Import the Modules + +# Readfile Functions which open the file that is passed to the script + +def readfile(filename): + print(filename) + f = open(filename, 'r') + line = f.read() + print(line) + + +def main(): + filename = '' + if len(sys.argv) == 2: # Check the arguments passed to the script + filename = sys.argv[1] # The filename is the first argument + if not os.path.isfile(filename): # Check the File exists + print('[-] ' + filename + ' does not exist.') + exit(0) + if not os.access(filename, os.R_OK): # Check you can read the file + print('[-] ' + filename + ' access denied') + exit(0) + else: + print('[-] Usage: ' + str(sys.argv[0]) + ' ') # Print usage if not all parameters passed/Checked + exit(0) + print('[+] Reading from : ' + filename) # Display Message and read the file contents + readfile(filename) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/closure.py b/closure.py index 47dd67c..57fe5dd 100644 --- a/closure.py +++ b/closure.py @@ -1,8 +1,9 @@ def hellocounter (name): - count=[0] + count=0 #PYTHON 2.x 中,要写count=[0] def counter(): - count[0]+=1 - print('Hello,',name,',',count[0],' access!') + nonlocal count #PYTHON 2.x 中,此行和下一行要换成count[0]+=1 + count+=1 + print('Hello,',name,',',count,' access!')#PYTHON 2.x 中请自觉换成str(count[0]) return counter hello = hellocounter('ma6174') @@ -10,6 +11,18 @@ def counter(): hello() hello() +''' +执行结果 +>>> hello() +Hello, ma6174 , 1 access! +>>> hello() +Hello, ma6174 , 2 access! +>>> hello() +Hello, ma6174 , 3 access! +''' +##为什么PYTHON 2.x中不直接写count而用list?这是python2的一个bug,如果用count话,会报这样一个错误: +##UnboundLocalError: local variable 'count' referenced before assignment. + def make_adder(addend): def adder(augend): return augend + addend diff --git a/conf/demo.conf b/conf/demo.conf new file mode 100644 index 0000000..0a7c581 --- /dev/null +++ b/conf/demo.conf @@ -0,0 +1,14 @@ +#demo.conf文件内容: + +[sec_a] +a_key1 = 20 +a_key2 = 10 + +[sec_b] +b_key1 = 121 +b_key2 = b_value2 +b_key3 = $r +b_key4 = 127.0.0.1 + +[website] +url = http://www.tantengvip.com \ No newline at end of file diff --git a/decorator.py b/decorator.py new file mode 100644 index 0000000..4e2c991 --- /dev/null +++ b/decorator.py @@ -0,0 +1,24 @@ +# coding=utf-8 + +# 定义一个装饰器 +def mydecorator(func): + def wrapper(*args,**kw): + print('hi,now is:') + return func(*args,**kw) + return wrapper + +# 使用装饰器 +@mydecorator +def now(): + print('2015-12-9') + +now() + +""" +D:\learn-python>python decorator.py +hi,now is: +2015年12月9日 + +关于装饰器的具体概念,参见: +http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000 +""" diff --git a/hasattr.py b/hasattr.py new file mode 100644 index 0000000..acb3ba2 --- /dev/null +++ b/hasattr.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Python hasattr判断是否存在属性 + +class Test: + + product11 = ['d'] + + def __init__(self): + pass + + def product(self, a, b): + return a * b + + def is_exists(self): + print(hasattr(self, 'product')) + + +test = Test() +test.is_exists() + + +""" +dir(test): +['__doc__', '__init__', '__module__', 'is_exists', 'product', 'product11'] +""" \ No newline at end of file diff --git a/method.py b/method.py new file mode 100644 index 0000000..80b22b2 --- /dev/null +++ b/method.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +# Python面向对象:类,类的方法,类方法,静态方法 + +class Person(object): + def __init__(self): + print('init') + + @staticmethod + def sayHello(hi): + if hi is None: + hi = 'hello' + print(hi) + + @classmethod + def hi(cls,msg): + print(msg) + print(dir(cls)) + + # 一般类的方法 + def hobby(self,hobby): + print(hobby) + +# 调用静态方法,不用实例化 +Person.sayHello('hi') +Person.hi('Hi!') + +# 实例化类调用普通方法,__init__在这里触发 +person = Person() +person.hobby('football') + + +""" +输出: +hi +Hi! +['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof_ +_', '__str__', '__subclasshook__', '__weakref__', 'hi', 'hobby', 'sayHello'] +init +football + +其中def hi(cls)这个类方法,cls表示类自身,所以输出跟dir(person)是一样的。 + +classmethod:类方法 +staticmethod:静态方法 + +在python中,静态方法和类方法都是可以通过类对象和类对象实例访问。但是区别是: + +1.@classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 +类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。 + +2.普通对象方法至少需要一个self参数,代表类对象实例 + +3.类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 +对于类方法,可以通过类来调用,就像C.f(),有点类似C++中的静态方法, 也可以通过类的一个实例来调用,就像C().f(),这里C(),写成这样之后它就是类的一个实例了。 + +4.静态方法则没有,它基本上跟一个全局函数相同,一般来说用的很少 +""" \ No newline at end of file diff --git a/niu.py b/niu.py index 9bbbd33..4c3d3c8 100644 --- a/niu.py +++ b/niu.py @@ -1,48 +1,54 @@ +# -*- coding:utf-8 -*- # 列举一副牌所有牌型为牛牛的情况 -# author:tanteng -import itertools,sys -#初始化一副牌(除去大小王) +__author__ = 'tanteng' + +import itertools, sys + + +# 初始化一副牌(除去大小王) def cards(): - cards = {'黑桃A':1,'红桃A':1,'方块A':1,'梅花A':1} - card_type = ['黑桃','红桃','方块','梅花'] + cards = {'黑桃A': 1, '红桃A': 1, '方块A': 1, '梅花A': 1} + card_type = ['黑桃', '红桃', '方块', '梅花'] - for c_type in card_type: - for no in range(2,11): - cards[c_type+str(no)] = no + for c_type in card_type: + for no in range(2, 11): + cards[c_type + str(no)] = no - for name in ['J','Q','K']: - cards[c_type+name] = 10 + for name in ['J', 'Q', 'K']: + cards[c_type + name] = 10 - return cards + return cards -#从一副牌取5张牌所有排列 + +# 从一副牌取5张牌所有排列 def all_cases(cards): - return list(itertools.combinations(cards,5)) + return list(itertools.combinations(cards, 5)) + if __name__ == '__main__': - cards = cards() - all_cases = all_cases(cards) - - print(len(all_cases)) - - for case in all_cases: - temp_name = list(case) - temp_value = [] - for ca in case: - temp_value.append(cards[ca]) - - sums = sum(temp_value) - if sums%10==0: - s_cases = list(itertools.combinations(temp_name,3)) - for s_case in s_cases: - temp_name2 = list(s_case) - temp_value2 = [] - for s_ca in s_case: - temp_value2.append(cards[s_ca]) - - sumc = sum(temp_value2) - if sumc%10==0: - print(temp_name) - break \ No newline at end of file + cards = cards() + all_cases = all_cases(cards) + + print(len(all_cases)) + + for case in all_cases: + temp_name = list(case) + temp_value = [] + for ca in case: + temp_value.append(cards[ca]) + + sums = sum(temp_value) + if sums % 10 == 0: + s_cases = list(itertools.combinations(temp_name, 3)) + for s_case in s_cases: + temp_name2 = list(s_case) + temp_value2 = [] + for s_ca in s_case: + temp_value2.append(cards[s_ca]) + + sumc = sum(temp_value2) + if sumc % 10 == 0: + print(temp_name) + break diff --git a/property.py b/property.py new file mode 100644 index 0000000..5193c53 --- /dev/null +++ b/property.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# 属性装饰器 +class Student(object): + @property + def score(self): + return self._score + + @score.setter + def score(self, value): + if not isinstance(value,int): + raise ValueError('必须输入数字!') + if value<0 or value>100: + raise ValueError('必须大于0小于100!') + self._score = value + +s = Student() +s.score = 101 +print(s.score) diff --git a/read_write_conf.py b/read_write_conf.py new file mode 100644 index 0000000..8448729 --- /dev/null +++ b/read_write_conf.py @@ -0,0 +1,88 @@ +# encoding:utf-8 + +# !/usr/bin/env python + +# -*- Python读写conf格式配置文件 -*- + +__author__ = 'tanteng' + + +import configparser +import webbrowser + +# 返回config对象 +conf = configparser.ConfigParser() +conf.read('./conf/demo.conf', 'utf-8') + +# 读取配置文件 +def readConf(): + # 得到所有sections + sections = conf.sections() + print(sections) + + # 得到sec_a,sec_b的设置项 + options_sec_a = conf.options('sec_a') + print(options_sec_a) + + options_sec_b = conf.options('sec_b') + print(options_sec_b) + + # 得到sec_a,sec_b的设置键值对 + items_sec_a = conf.items('sec_a') + print(items_sec_a) + + items_sec_b = conf.items('sec_b') + print(items_sec_b) + + # 得到具体某个section某个option的值 + sec_a_key1 = conf.get('sec_a','a_key1') + print(sec_a_key1) + +readConf() + +''' +readConf()运行结果: + +['sec_a', 'sec_b'] +['a_key1', 'a_key2'] +['b_key1', 'b_key2', 'b_key3', 'b_key4'] +[('a_key1', '20'), ('a_key2', '10')] +[('b_key1', '121'), ('b_key2', 'b_value2'), ('b_key3', '$r'), ('b_key4', '127.0.0.1')] +20 +''' + +# 写配置文件 +def writeConf(): + # 更新某个section某个option的值 + conf.set('sec_a','a_key1','100') # 最后一个参数必须是string类型 + value = conf.get('sec_a','a_key1') + print(value) # 打印结果看是否设置成功 + + conf.add_section('new_section') + conf.set('new_section','new_option_name','new_option_value') + + new_sections = conf.sections() + + # 检测是否新增section和新增设置项成功 + print(new_sections) + print(conf.get('new_section','new_option_name')) + + +writeConf() + +''' +writeConf()运行结果: + +100 +['sec_a', 'sec_b', 'website', 'new_section'] +new_option_value +tantengdeMacBook-Pro:learn-python tanteng$ +''' + +# 更多Python3入门文章,读取网址配置跳转,现学现用 + +def jump(): + url = conf.get('website','url') + webbrowser.open(url) + +jump() diff --git a/save_remote_image.py b/save_remote_image.py new file mode 100644 index 0000000..87f92a0 --- /dev/null +++ b/save_remote_image.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +# 使用requests保存远程图片(或文件) +import requests +import os + + +def saveRemoteImage(): + imgurl = 'http://www.tantengvip.com/wp-content/uploads/2015/01/cropped-13887362_13887362_1347773771848.jpg' + filename = imgurl.split('/')[-1] + path = './static/'+filename + if not os.path.exists(path): + r = requests.get(imgurl) + with open(path, 'wb') as f: + f.write(r.content) + print('OK') + else: + print('Already exists.') + + """ + 下载大文件这样写: + for chunk in r.iter_content(): + f.write(chunk) + + 如果不使用requests模块: + import urllib + urllib.urlretrieve(url, filename=None, reporthook=None, data=None) + """ + +saveRemoteImage() diff --git a/singleton.py b/singleton.py new file mode 100644 index 0000000..43fe467 --- /dev/null +++ b/singleton.py @@ -0,0 +1,15 @@ +# encoding:utf-8 + +# -*- Python单例模式示例 -*- + +class Singleton(object): + def __new__(cls): + if not hasattr(cls, 'instance'): + cls.instance = super(Singleton, cls).__new__(cls) + return cls.instance + +if __name__ == '__main__': + a = Singleton() + b = Singleton() + print(id(a)) + print(id(b)) diff --git a/static/cropped-13887362_13887362_1347773771848.jpg b/static/cropped-13887362_13887362_1347773771848.jpg new file mode 100644 index 0000000..a704f14 Binary files /dev/null and b/static/cropped-13887362_13887362_1347773771848.jpg differ diff --git a/sys_argv.py b/sys_argv.py index 5bbcfa4..bf64c6e 100644 --- a/sys_argv.py +++ b/sys_argv.py @@ -1,24 +1,81 @@ +# encoding:utf-8 + +# !/usr/bin/env python + +# -*- Python3命令行 -*- + +import optparse import sys +import webbrowser + + +def process_command_line(argv): + """ + Return a 2-tuple: (settings object, args list). + `argv` is a list of arguments, or `None` for ``sys.argv[1:]``. + """ + if argv is None: + argv = sys.argv[1:] + # initialize the parser object: + parser = optparse.OptionParser( + formatter=optparse.TitledHelpFormatter(width=78), + add_help_option=None) + # define options here: + parser.add_option( # customized description; put --help last + '-h', '--help', action='help', help='Show this help message and exit.' + ) + parser.add_option( + '-u', '--url', action='store', dest = 'link', help='Open a link.' + ) + parser.add_option( + '-v', '--version', action='store_true', help='Show version.' + ) + parser.add_option( + '-q', '--quit', action='store_false',help='Quit' + ) + settings, args = parser.parse_args(argv) + # check number of arguments, verify values, etc.: + if args: + parser.error('program takes no command-line arguments; ' + '"%s" ignored.' % (args,)) + # further process settings & args if necessary + return settings, args + +def main(argv=None): + settings, args = process_command_line(argv) + print(settings) + # application code here, like: + run(settings, args) + return 0 # success + +def run(settings, args): + if settings.link: + webbrowser.open(settings.link, 1) + + if settings.version: + print('VERSION 1.0') + -# sys.argv接收参数,第一个参数是文件名,第二个参数开始是用户输入的参数,以空格隔开 -def run1(): - print('I\'m action1') +if __name__ == '__main__': + status = main() + sys.exit(status) +""" +命令行功能: -def run2(): - print('I\'m action2') +python sys_argv.py -h +显示帮助信息 +python sys_argv.py -v +显示版本号 -if 2> len(sys.argv): - print('none') -else: - action1 = sys.argv[1] - action2 = sys.argv[2] +python sys_argv.py -u www.163.com +用默认浏览器打开你输入的网址 - if 'run1' == action1: - run1() - if 'run2' == action2: - run2() - -#用法:在命令行执行脚本,python sys_argv.py run1 run2 +action四种参数: +help 显示帮助信息 +store 需要参数值 +store_true 不需要参数值,默认True +store_false 不需要参数值,默认False +""" \ No newline at end of file diff --git a/test_redis.py b/test_redis.py index f5c6ee3..ce08993 100644 --- a/test_redis.py +++ b/test_redis.py @@ -1,8 +1,30 @@ +# encoding:utf-8 + import redis +import webbrowser + + r = redis.StrictRedis(host='localhost', port=6379, db=0) -r.set('foo', 'bar') +r.set('foo', 'bar') foo = r.get('foo') -print(foo) -# b'bar' \ No newline at end of file +r.sadd('collection','abc') +r.sadd('collection','def') +r.sadd('collection','fhi') +r.sadd('collection','xwy') + +r.zadd('rank',1,'Alibaba') +r.zadd('rank',2,'Tencent') +r.zadd('rank',3,'Baidu') +r.zadd('rank',baidu=3,cc=3,ccc=34) +r.zadd('rank',4,6) + +r.rpush('list','www.tantengvip.com') +r.rpush('list','www.qq.com') +r.rpush('list','www.tencent.com') + +pop = r.lpop('list') +print(pop) + +webbrowser.open('http://www.tantengvip.com',1) diff --git a/testrequests.py b/testrequests.py new file mode 100644 index 0000000..27a803e --- /dev/null +++ b/testrequests.py @@ -0,0 +1,22 @@ +__author__ = 'tanteng' + +import requests + +def testrequests(): + + url = 'http://www.x.com/index/pyrequests' + + params = { + 'x':'xxxx', + 'y':'yyyy' + } + + re = requests.get(url,params) + + return re + + +if __name__ == '__main__': + re = testrequests() + print(re.text) + diff --git a/wechat-ledongli.py b/wechat-ledongli.py new file mode 100644 index 0000000..6d3a8c7 --- /dev/null +++ b/wechat-ledongli.py @@ -0,0 +1,117 @@ +#coding: utf-8 + +#date: 刷微信步数 + +#usage: edit steps and ledongli's uid(u need to download this app) .That would be ok .Good luck. ^_^ + +import requests + +import sys + +import json + +import datetime + +import time + +def isnum(value): + + try: + + temp = int(value) + + except Exception as e: + + return False + + else: + + return True + +# like 2015年09月25日 00:00:00 converts to unix time stamp + +def formatDate(): + + nowtime = datetime.datetime.now() + + date = time.strftime('%Y-%m-%d') + + strtemp_date = date + ' 00:00:00' + + ledongli_date = time.strptime(strtemp_date, '%Y-%m-%d %H:%M:%S') + + finaldate = time.mktime(ledongli_date) # rusult is 1443456000.0(float type), but still need to format to 1443456000 + + finaldate = int(finaldate) + + return finaldate + +def main(steps, uid): + + if not isnum(steps): + + print('param error. steps must be an integer.') + + url = 'http://pl.api.ledongli.cn/xq/io.ashx' + + fake_headers = { + + 'User-Agent' : 'le dong li/5.4 (iPhone; iOS 9.1; Scale/2.00)', + + 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8', + + 'Accept-Encoding': 'gzip' + + } + + keycontentjson = [ + + { + + "date": formatDate(), + "calories": 0, + "activeValue": 108, + "steps": steps, + "pm2d5": 0, + "duration": 0, + "distance": 0, + "report": "[]" + + } + + ] + + # key is a str type + + # key must be a json data convert to string + + key = json.dumps(keycontentjson) + + param = { + + 'action': 'profile', + + 'pc': '29e39ed274ea8e7a50f8a83abf1239faca843022', + + 'cmd': 'updatedaily', + + 'uid': uid, + + 'list': key, + 'v' : '5.4%20ios', + 'vc' : '540%20ios' + } + + r = requests.post(url, data = param, headers = fake_headers) + + print(r.text) + + print('装逼成功') + +if __name__ == '__main__': + + steps = 199999 + + uid = '1111111' + + main(steps, uid) \ No newline at end of file

AltStyle によって変換されたページ (->オリジナル) /