python的学习小结

2016-12-21  本文已影响0人  kruuuuuuust

__all__的用法

常常看源码发现__init__.py文件中有__all__,关于它的用法举个栗子:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): 
  return 'baz'

__all__仅仅影响from foo import *,会认为没在__all__中的对象无法导入.

from foo import *
print bar
print baz
# waz将会报异常
print waz

但如果使用from foo import waz,则能够导入waz.

classmethod与staticmethod

类方法classmethod常用来创建一个类的实例,非常像c++中的构造函数.

class C: 
  @staticmethod 
  def f(cls, arg1, arg2, ...): # 第一个参数为cls
    cls_ = cls(arg1, arg2)
    return cls_

静态方法staticmethod可以被类调用C.f()实例调用C().f().用于常驻内存,并与实例无关的公共方法场景.

class C: 
  @staticmethod 
  def f(arg1, arg2, ...): 
    pass

uuid

uuid(UUID objects according to RFC 4122),工作中常使用uuid模块来产生唯一通用标示符,代表不同的用户.

import uuid
uuid1()
uuid2()
uuid3()
uuid4()

super()

调用父类方法时.

class C(B): 
def method(self, arg): 
  super(C, self).method(arg)

等价于:

class C(B): 
def method(self, arg): 
  super().method(arg)    

super()只能super().__getitem__(name)来显式调用方法,不能super()[name]这样的隐式调用.

isinstance(a, (b, c, d))

是下面方式的优雅的表达:

if type(a) in (b, c, d):
  return True
else
  return False

创建class

class X:
  a = 1

等价于

X = type('X', (object,), dict(a=1))

class type(name, bases, dict)name是类名,bases是父类,dict是成员的字典.

字典类型初始化

d = {'a':1}
d.get('b',2)  # b不在字典d中,获取时初始化b为2

locals()查看本地变量

注释会在__doc__出现,申明的变量直接出现,__file__是文件绝对路径.

{
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fbdc7a04278>, 
'__doc__': '\n  all is here\n', 
'__file__': '/home/kushao1267/workspace/restless/restless/ss.py', 
'a': [1, 2, 3],  # 申明的变量
'__package__': None, 
'__cached__': None, 
'__name__': '__main__', 
'__builtins__': <module 'builtins' (built-in)>, 
'__spec__': None
}

zip与unzip

a = [1, 2, 3]
b = [4, 5, 6]

def zip_func(a, b):
    """
        [1, 2, 3],[4, 5, 6] --> [(1, 4), (2, 5), (3, 6)]
    """
    zip_ = list(zip(a, b))
    return zip_

def unzip_func(zip_):
    """
        [(1, 4), (2, 5), (3, 6)] --> [(1, 2, 3), (4, 5, 6)]
    """
    a, b = list(zip(*zip_))  # zip(*) 是解压
    return list(a), list(b)

if __name__ == '__main__':
    zip_ = zip_func(a, b)
    a, b = unzip_func(zip_)
    print(zip_, a, b)

关键词使用

常常在开发中使用python已有的关键词,例如class,type,所以我们常常用class_,type_以区分,因为class和type都是对象,能够被赋值,后面coding时容易出现错误.

try...except...else语句

try:
  todo
except:
  # catch Exception
else:
  todo  # try未触发异常时执行此处

python下的路径

import os
def function():
    print(os.path.abspath(__file__))  # 当前脚本所在绝对路径
    print(os.path.dirname(os.path.abspath(__file__)))  # 当前脚本所在的路径
    print(os.path.dirname(os.path.dirname(
        os.path.abspath(__file__))))  # 当前脚本所在的上移级路径

if __name__ == '__main__':
    function()

输出为

/home/kushao1267/ss_work/test.py
/home/kushao1267/ss_work
/home/kushao1267
[Finished in 0.3s]

所以,__file__代表即为当前脚本文件,os.path.abspath()方法获取一个文件的绝对路径,os.path.dirname()获取其路径名或上一级路径名.

itertools的chain()

很多时候需要对不同的容器中的对象进行相同处理

import itertool
a = [1,2,3]
b= [3,4,5]
for i in itertool.chain(a,b):
print(i)

而下面的方式内存消耗将会大很多,因为会创建a+b的一个容器

for i in a+b:
print(i)

with语句

with语句的上下文context是通过来实现嵌套的.
比如:

with A() as a, B() as b: 
  suite

等价于

withA()asa:
  withB()asb:
    suite

上下文管理器contextmanager

@contextlib.contextmanager 修饰器可用于with语句中,且免于自己定义__enter__()__exit__()方法
例如:

fromcontextlibimportcontextmanager
@contextmanager
deftag(name):
  print("<%s>"%name)//此处的code相当于__enter__()
  yield//等待todo语句完成
  print("</%s>"%name)//此处的code相当于__exit__()
>>>withtag("h1"):
...  print("foo")//todo语句
...
<h1>
foo
</h1>

上下文装饰器ContextDecorator

定义上下文装饰器

from contextlib import ContextDecorator
class mycontext(ContextDecorator): 
  def __enter__(self): 
    print('Starting') 
    return self 
  def __exit__(self, *exc): 
    print('Finishing') 
    return False

装饰器方式如下:

>>> @mycontext()  
... def function():
... print('The bit in the middle')
...
>>> function()
Starting
The bit in the middle
Finishing

with语句方式如下:

   >>> with mycontext():  
   ... print('The bit in the middle')
   ...Starting
      The bit in the middle
      Finishing

function()中的内容将在继承ContextDecorator的装饰器mycontext()的__enter__()__exit__()之间执行.

上一篇下一篇

猜你喜欢

热点阅读