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 f9f3681..4095ca7 100644 --- a/args_kwargs.py +++ b/args_kwargs.py @@ -1,10 +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/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/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)