Python 奇技淫巧

简介: Python 奇技淫巧 显示有限的接口到外部 当发布python第三方package时,并不希望代码中所有的函数或者class可以被外部import,在__init__.py中添加__all__属性,该list中填写可以import的类或者函数名, 可以起到限制的import的作用, 防止外部import其他函数或者类。


显示有限的接口到外部

当发布python第三方package时,并不希望代码中所有的函数或者class可以被外部import,在__init__.py中添加__all__属性,该list中填写可以import的类或者函数名, 可以起到限制的import的作用, 防止外部import其他函数或者类。


  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from base import APIBase
  4. from client import Client
  5. from decorator import interface, export, stream
  6. from server import Server
  7. from storage import Storage
  8. from util import (LogFormatter, disable_logging_to_stderr,
  9. enable_logging_to_kids, info)
  10. __all__ = ['APIBase', 'Client', 'LogFormatter', 'Server',
  11. 'Storage', 'disable_logging_to_stderr', 'enable_logging_to_kids',
  12. 'export', 'info', 'interface', 'stream']

with的魔力

with语句需要支持上下文管理协议的对象, 上下文管理协议包含__enter____exit__两个方法。 with语句建立运行时上下文需要通过这两个方法执行进入和退出操作。

其中上下文表达式是跟在with之后的表达式, 该表达式返回一个上下文管理对象。


  
  
  1. # 常见with使用场景
  2. with open("test.txt", "r") as my_file: # 注意, __enter__()方法的返回值赋值给了my_file,
  3. for line in my_file:
  4. print line

详细原理可以查看这篇文章, 浅谈 Python 的 with 语句

知道具体原理,我们可以自定义支持上下文管理协议的类,类中实现__enter____exit__方法。


  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. class MyWith(object):
  4. def __init__(self):
  5. print "__init__ method"
  6. def __enter__(self):
  7. print "__enter__ method"
  8. return self # 返回对象给as后的变量
  9. def __exit__(self, exc_type, exc_value, exc_traceback):
  10. print "__exit__ method"
  11. if exc_traceback is None:
  12. print "Exited without Exception"
  13. return True
  14. else:
  15. print "Exited with Exception"
  16. return False
  17. def test_with():
  18. with MyWith() as my_with:
  19. print "running my_with"
  20. print "------分割线-----"
  21. with MyWith() as my_with:
  22. print "running before Exception"
  23. raise Exception
  24. print "running after Exception"
  25. if __name__ == '__main__':
  26. test_with()

执行结果如下:


  
  
  1. __init__ method
  2. __enter__ method
  3. running my_with
  4. __exit__ method
  5. Exited without Exception
  6. ------分割线-----
  7. __init__ method
  8. __enter__ method
  9. running before Exception
  10. __exit__ method
  11. Exited with Exception
  12. Traceback (most recent call last):
  13. File "bin/python", line 34, in <module>
  14. exec(compile(__file__f.read(), __file__, "exec"))
  15. File "test_with.py", line 33, in <module>
  16. test_with()
  17. File "test_with.py", line 28, in test_with
  18. raise Exception
  19. Exception

证明了会先执行__enter__方法, 然后调用with内的逻辑, 最后执行__exit__做退出处理, 并且, 即使出现异常也能正常退出

filter的用法

相对filter而言, map和reduce使用的会更频繁一些, filter正如其名字, 按照某种规则过滤掉一些元素。


  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. lst = [1, 2, 3, 4, 5, 6]
  4. # 所有奇数都会返回True, 偶数会返回False被过滤掉
  5. print filter(lambda x: x % 2 != 0, lst)
  6. #输出结果
  7. [1, 3, 5]

一行作判断

当条件满足时, 返回的为等号后面的变量, 否则返回else后语句。


  
  
  1. lst = [1, 2, 3]
  2. new_lst = lst[0] if lst is not None else None
  3. print new_lst
  4. # 打印结果
  5. 1

装饰器之单例

使用装饰器实现简单的单例模式


  
  
  1. # 单例装饰器
  2. def singleton(cls):
  3. instances = dict() # 初始为空
  4. def _singleton(*args, **kwargs):
  5. if cls not in instances: #如果不存在, 则创建并放入字典
  6. instances[cls] = cls(*args, **kwargs)
  7. return instances[cls]
  8. return _singleton
  9. @singleton
  10. class Test(object):
  11. pass
  12. if __name__ == '__main__':
  13. t1 = Test()
  14. t2 = Test()
  15. # 两者具有相同的地址
  16. print t1, t2

staticmethod装饰器

类中两种常用的装饰, 首先区分一下他们:

  • 普通成员函数, 其中第一个隐式参数为对象
  • classmethod装饰器, 类方法(给人感觉非常类似于OC中的类方法), 其中第一个隐式参数为
  • staticmethod装饰器, 没有任何隐式参数. python中的静态方法类似与C++中的静态方法

  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. class A(object):
  4. # 普通成员函数
  5. def foo(self, x):
  6. print "executing foo(%s, %s)" % (self, x)
  7. @classmethod # 使用classmethod进行装饰
  8. def class_foo(cls, x):
  9. print "executing class_foo(%s, %s)" % (cls, x)
  10. @staticmethod # 使用staticmethod进行装饰
  11. def static_foo(x):
  12. print "executing static_foo(%s)" % x
  13. def test_three_method():
  14. obj = A()
  15. # 直接调用噗通的成员方法
  16. obj.foo("para") # 此处obj对象作为成员函数的隐式参数, 就是self
  17. obj.class_foo("para") # 此处类作为隐式参数被传入, 就是cls
  18. A.class_foo("para") #更直接的类方法调用
  19. obj.static_foo("para") # 静态方法并没有任何隐式参数, 但是要通过对象或者类进行调用
  20. A.static_foo("para")
  21. if __name__ == '__main__':
  22. test_three_method()
  23. # 函数输出
  24. executing foo(<__main__.A object at 0x100ba4e10>, para)
  25. executing class_foo(<class '__main__.A'>, para)
  26. executing class_foo(<class '__main__.A'>, para)
  27. executing static_foo(para)
  28. executing static_foo(para)

property装饰器

  • 定义私有类属性

property与装饰器结合实现属性私有化(更简单安全的实现get和set方法)。


  
  
  1. #python内建函数
  2. property(fget=None, fset=None, fdel=None, doc=None)

fget是获取属性的值的函数,fset是设置属性值的函数,fdel是删除属性的函数,doc是一个字符串(像注释一样)。从实现来看,这些参数都是可选的。

property有三个方法getter(), setter()delete() 来指定fget, fset和fdel。 这表示以下这行:


  
  
  1. class Student(object):
  2. @property #相当于property.getter(score) 或者property(score)
  3. def score(self):
  4. return self._score
  5. @score.setter #相当于score = property.setter(score)
  6. def score(self, value):
  7. if not isinstance(value, int):
  8. raise ValueError('score must be an integer!')
  9. if value < 0 or value > 100:
  10. raise ValueError('score must between 0 ~ 100!')
  11. self._score = value

iter魔法

  • 通过yield和__iter__的结合,我们可以把一个对象变成可迭代的
  • 通过__str__的重写, 可以直接通过想要的形式打印对象

  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. class TestIter(object):
  4. def __init__(self):
  5. self.lst = [1, 2, 3, 4, 5]
  6. def read(self):
  7. for ele in xrange(len(self.lst)):
  8. yield ele
  9. def __iter__(self):
  10. return self.read()
  11. def __str__(self):
  12. return ','.join(map(str, self.lst))
  13. __repr__ = __str__
  14. def test_iter():
  15. obj = TestIter()
  16. for num in obj:
  17. print num
  18. print obj
  19. if __name__ == '__main__':
  20. test_iter()

神奇partial

partial使用上很像C++中仿函数(函数对象)。

在stackoverflow给出了类似与partial的运行方式:


  
  
  1. def partial(func, *part_args):
  2. def wrapper(*extra_args):
  3. args = list(part_args)
  4. args.extend(extra_args)
  5. return func(*args)
  6. return wrapper

利用用闭包的特性绑定预先绑定一些函数参数,返回一个可调用的变量, 直到真正的调用执行:


  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from functools import partial
  4. def sum(a, b):
  5. return a + b
  6. def test_partial():
  7. fun = partial(sum, 2) # 事先绑定一个参数, fun成为一个只需要一个参数的可调用变量
  8. print fun(3) # 实现执行的即是sum(2, 3)
  9. if __name__ == '__main__':
  10. test_partial()
  11. # 执行结果
  12. 5

神秘eval

eval我理解为一种内嵌的python解释器(这种解释可能会有偏差), 会解释字符串为对应的代码并执行, 并且将执行结果返回。

看一下下面这个例子:


  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. def test_first():
  4. return 3
  5. def test_second(num):
  6. return num
  7. action = { # 可以看做是一个sandbox
  8. "para": 5,
  9. "test_first" : test_first,
  10. "test_second": test_second
  11. }
  12. def test_eavl():
  13. condition = "para == 5 and test_second(test_first) > 5"
  14. res = eval(condition, action) # 解释condition并根据action对应的动作执行
  15. print res
  16. if __name__ == '_

exec

  • exec在Python中会忽略返回值, 总是返回None, eval会返回执行代码或语句的返回值
  • execeval在执行代码时, 除了返回值其他行为都相同
  • 在传入字符串时, 会使用compile(source, '<string>', mode)编译字节码。 mode的取值为execeval

  
  
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. def test_first():
  4. print "hello"
  5. def test_second():
  6. test_first()
  7. print "second"
  8. def test_third():
  9. print "third"
  10. action = {
  11. "test_second": test_second,
  12. "test_third": test_third
  13. }
  14. def test_exec():
  15. exec "test_second" in action
  16. if __name__ == '__main__':
  17. test_exec() # 无法看到执行结果

getattr

getattr(object, name[, default])返回对象的命名属性,属性名必须是字符串。如果字符串是对象的属性名之一,结果就是该属性的值。例如, getattr(x, ‘foobar’) 等价于 x.foobar。 如果属性名不存在,如果有默认值则返回默认值,否则触发 AttributeError 。


  
  
  1. # 使用范例
  2. class TestGetAttr(object):
  3. test = "test attribute"
  4. def say(self):
  5. print "test method"
  6. def test_getattr():
  7. my_test = TestGetAttr()
  8. try:
  9. print getattr(my_test, "test")
  10. except AttributeError:
  11. print "Attribute Error!"
  12. try:
  13. getattr(my_test, "say")()
  14. except AttributeError: # 没有该属性, 且没有指定返回值的情况下
  15. print "Method Error!"
  16. if __name__ == '__main__':
  17. test_getattr()
  18. # 输出结果
  19. test attribute
  20. test method

命令行处理


  
  
  1. def process_command_line(argv):
  2. """
  3. Return a 2-tuple: (settings object, args list).
  4. `argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
  5. """
  6. if argv is None:
  7. argv = sys.argv[1:]
  8. # initialize the parser object:
  9. parser = optparse.OptionParser(
  10. formatter=optparse.TitledHelpFormatter(width=78),
  11. add_help_option=None)
  12. # define options here:
  13. parser.add_option( # customized description; put --help last
  14. '-h', '--help', action='help',
  15. help='Show this help message and exit.')
  16. settings, args = parser.parse_args(argv)
  17. # check number of arguments, verify values, etc.:
  18. if args:
  19. parser.error('program takes no command-line arguments; '
  20. '"%s" ignored.' % (args,))
  21. # further process settings & args if necessary
  22. return settings, args
  23. def main(argv=None):
  24. settings, args = process_command_line(argv)
  25. # application code here, like:
  26. # run(settings, args)
  27. return 0 # success
  28. if __name__ == '__main__':
  29. status = main()
  30. sys.exit(status)

读写csv文件


  
  
  1. # csv中读取文件, 基本和传统文件读取类似
  2. import csv
  3. with open('data.csv', 'rb') as f:
  4. reader = csv.reader(f)
  5. for row in reader:
  6. print row
  7. # csv文件写入
  8. import csv
  9. with open( 'data.csv', 'wb') as f:
  10. writer = csv.writer(f)
  11. writer.writerow(['name', 'address', 'age']) # 单行写入
  12. data = [
  13. ( 'xiaoming ','china','10'),
  14. ( 'Lily', 'USA', '12')]
  15. writer.writerows(data) # 多行写入

各种时间形式转换

只发一张网上的图, 然后查文档就好了, 这个是记不住的

字符串格式化

一个非常好用, 很多人又不知道的功能:


  
  
  1. >>> name = "andrew"
  2. >>> "my name is {name}".format(name=name)
  3. 'my name is andrew'

参考链接

本文来自云栖社区合作伙伴“Linux中国”,原文发表于2013-04-02.
相关文章
|
测试技术 Python
Python奇技淫巧—[1]—在列表、字典、集合中根据条件筛选数据
Python奇淫巧技——在列表、字典、集合中根据条件筛选数据 通用做法:迭代 以列表为例: 筛选出下列数字大于等于0的数 data = [2, 7, -4, -1, 3, 0, 8] res = [] for i in data: if i >= 0: res.
1385 0
|
索引 Python
Python奇技淫巧—[2]—使用元组代替字典,同时为元组元素命名,提高可读性
Python奇淫巧技——使用元组代替字典,同时为元组元素命名,提高可读性 场景: 一般使用字典定义一个人的姓名,年龄,性别,邮箱等信息是非常方便的,比如: student_one = {'name': 'Tom', 'age': 19, 'sex': 'male', 'email': 'tom123@hotmail.
1157 0
|
Python
Python奇技淫巧
Python奇技淫巧      http://andrewliu.in/2015/11/14/Python%E5%A5%87%E6%8A%80%E6%B7%AB%E5%B7%A7/?hmsr=toutiao.
994 0
|
13天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
12天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
19天前
|
存储 索引 Python
Python编程数据结构的深入理解
深入理解 Python 中的数据结构是提高编程能力的重要途径。通过合理选择和使用数据结构,可以提高程序的效率和质量
131 59
|
12天前
|
小程序 开发者 Python
探索Python编程:从基础到实战
本文将引导你走进Python编程的世界,从基础语法开始,逐步深入到实战项目。我们将一起探讨如何在编程中发挥创意,解决问题,并分享一些实用的技巧和心得。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供有价值的参考。让我们一起开启Python编程的探索之旅吧!
36 10
|
15天前
|
机器学习/深度学习 人工智能 Java
Python 语言:强大、灵活与高效的编程之选
本文全面介绍了 Python 编程语言,涵盖其历史、特点、应用领域及核心概念。从 1989 年由 Guido van Rossum 创立至今,Python 凭借简洁的语法和强大的功能,成为数据科学、AI、Web 开发等领域的首选语言。文章还详细探讨了 Python 的语法基础、数据结构、面向对象编程等内容,旨在帮助读者深入了解并有效利用 Python 进行编程。
|
14天前
|
机器学习/深度学习 人工智能 数据挖掘
探索Python编程的奥秘
在数字世界的海洋中,Python如同一艘灵活的帆船,引领着无数探险者穿梭于数据的波涛之中。本文将带你领略Python编程的魅力,从基础语法到实际应用,一步步揭开Python的神秘面纱。
34 12
|
13天前
|
IDE 程序员 开发工具
Python编程入门:打造你的第一个程序
迈出编程的第一步,就像在未知的海洋中航行。本文是你启航的指南针,带你了解Python这门语言的魅力所在,并手把手教你构建第一个属于自己的程序。从安装环境到编写代码,我们将一步步走过这段旅程。准备好了吗?让我们开始吧!