chili coding 自留地

python 高级技巧


本文目录

  • 装饰器
  • 生成器
  • 迭代器
  • hasattr getattr setattr
  • 递推构造
  • super
  • 单例模式
  • reduce
  • __repr__ 和 __str__
  • read readline readlines

装饰器

1,打印信息

def wraper(main_func):
    def _(*func_args):
        print('main func')
        return main_func(*func_args)

    return _


@wraperdef log(a, b):
    print(a, b)


log(1, 2)

输出:

main func
1 2

2,带参数

def wraper2(*deco_args):
    print('deco_paras', *deco_args)

    def wraper(main_func):
        def _(*func_args):
            print('main func')
            return main_func(*func_args)

        return _

    return wraper


@wraper2(1, 2, 3)
def log(a, b):
    print(a, b)


log(1, 2)

输出:

deco_paras 1 2 3
main func
1 2

生成器

L = [x * x for x in range(10)]
# L
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

g = (x * x for x in range(10))
# g
# <generator object <genexpr> at 0x104feab40>

用 yield 可以实现一个

def generator_range(n):
    i = 0    while i != n:
        yield i
        i += 1
r = generator_range(100)

# r
# <generator object generator_range at 0x10c153e60>

可以用 next 方法一个一个获取元素

print(r.__next__())
print(next(r))
print(next(r))
print(next(r))

输出

0
1
2
3

一般用 for 循环遍历生成器元素

for i in r:
    print(i)
0
1
...

迭代器

class Data():
def __init__(self, max):
self.max = max
self.data = 0

def __iter__(self):
return self

def __next__(self):
if self.data >= self.max:
raise StopIteration
else:
self.data += 1
return self.data


d = Data(100)

from collections import Iterable

print(isinstance(d, Iterable))
for i in range(3):
print(next(d))
True
1
2
3

hasattr getattr setattr

class test():
    name = 'hello'    

    def run(self):
        return 'hello world'


t = test()
print(hasattr(t, 'name'))
print(hasattr(t, 'run'))
print(hasattr(t, 'foo'))

# True
# True
# False

print(getattr(t, 'name'))
print(getattr(t, 'run'))
getattr(t, 'run')()

# hello
# <bound method test.run of <__main__.test object at 0x100d86860>>
# hello world

# 默认参数
print(getattr(t, 'foo', 'world'))
# world


# 设置参数
setattr(t, "age", "18")

# 一个综合的用法
getattr(t, "age", setattr(t, "age", "18")) 

# 还可以添加方法
def foo():
    print('haha')
    
setattr(t, 'foo', foo)

getattr(t, 'foo')()

# haha

递推构造

# 列表
[i * i for i in range(100)]

# 字典
{i : i * i for i in range(100)}

# 生成器
(i * i for i in range(100))

# 组合
[
  (x, y, z) for x in range(1, 20) 
           for y in range(x, 20) 
           for z in range(y, 20) 
  if x**2 + y**2 == z**2
]

# [
    (3, 4, 5), 
    (5, 12, 13),
    (6, 8, 10),
  ]

super

class A:
    def add(self, x):
        y = x + 1        
        print(y)


class B(A):
    def add(self, x):
        super().add(x)


b = B()
b.add(2) 
# 3



单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

之前在写游戏的时候用到过,JavaScript 代码如下

class GuaGame {
    constructor(fps, images, runCallback) {
        ...
    }

    static instance(...args) {
        this.i = this.i || new this(...args)
        return this.i
    }
}

python 实现方法如下(有多种方法,最方便的时候使用__new__实现实现单例之后,生成的实例就是同一个实例

import threading
class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = super().__new__(cls)  
        return Singleton._instance


obj1 = Singleton()
obj2 = Singleton()

print(id(obj1))
print(id(obj2))

# 4359890816
# 加锁是为了多线程时的安全性


reduce

from functools import reduce

a = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
print(a)

# 15


b = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
print(b)

# 25


__repr__ 和 __str__

https://blog.csdn.net/sinat_41104353/article/details/79254149

>>> class A:
	pass

>>> a1 = A()
>>> a1
<__main__.A object at 0x000000000302C358>

>>> print(a1)
<__main__.A object at 0x000000000302C358>

#
>>> class A:
	def __str__(self):        
		return "我是一个字符串"                                                                      

>>> a1 = A()
>>> a1
<__main__.A object at 0x00000000033712E8>
 
>>> print(a1)
我是一个字符串

#
>>> class A:
	def __repr__(self):   #返回一个可以用来表示对象的可打印字符串
		return "我是一个字符串"

>>> a1 = A()
>>> a1
我是一个字符串

>>> print(a1)
我是一个字符串

#
>>> class A:
	def __str__(self):
		return "__str__"

	def __repr__(self):   

		return "__repr__"

>>> a1 = A()
>>> a1
__repr__

>>> print(a1)
__str__

read readline readlines

read 
  读取整个文本,输出一个字符串

readline
  输出一个生成器,一行一行的获得,可以用 next 或者 for

readlines
  读取整个文本,输出一个数组,每行内容一个元素


reply ( 0 )