Skip to content

python 中的奇淫技巧

列了一些我新發現的各種花招

Function Attributes 2.1

PEP 232

def a():
    a.count += 1

a.count = 0

for i in range(10):
    a()

print(a.count)
10

跟 C++ 中,在 function 裡面宣告 static 變數差不多

Keyword-Only Arguments 3.0

PEP 3102

def func(a, b, *, c = None):
    pass
  • func(1, 2, 3)
  • func(1, 2, c = 3)

Additional Unpacking Generalizations 3.5

PEP 448

a = [1, 2, 3]
b = [*a, 4, 5]
print(b)
[1, 2, 3, 4, 5]

Merge Dicts

a = {1: 2}
b = {3: 4}
c = {**a, **b}
print(c)
{1: 2, 3: 4}

Metaclasses

Python Metaclasses

class A:
    pass

B = type('B',
         (A,),
         {
            'attr': 10,
            'func': lambda obj: obj.attr
         })

b = B()
print(b.attr)
print(b.func())
class A:
    pass

class B(A):
    attr = 10
    def func(self):
        return self.attr

b = B()
print(b.attr)
print(b.func())
10
10

看看就好xD

shallow vs deep copy

Shallow vs Deep Copying of Python Objects

assign

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

b.append('hello')
b[0].append('world')

print(a)
print(b)
[[1, 2, 3, 'world'], [4, 5, 6], 'hello']
[[1, 2, 3, 'world'], [4, 5, 6], 'hello']

copy

import copy

a = [[1, 2, 3], [4, 5, 6]]
b = copy.copy(a)

b.append('hello')
b[0].append('world')

print(a)
print(b)
[[1, 2, 3, 'world'], [4, 5, 6]]
[[1, 2, 3, 'world'], [4, 5, 6], 'new object']

deepcopy

import copy

a = [[1, 2, 3], [4, 5, 6]]
b = copy.deepcopy(a)

b.append('hello')
b[0].append('world')

print(a)
print(b)
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3, 'world'], [4, 5, 6], 'new object']
  • copy.copy (shallow) 只複製該物件,不會複製子物件
  • copy.deepcopy (deep) 會遞迴複製所有子物件

shallow copy on list

a = [1, 2, 3]
b = list(a)
a = [1, 2, 3]
b = a[:]
a = [1, 2, 3]
b = a.copy()
import copy

a = [1, 2, 3]
b = copy.copy(a)

annotations

function annotations

def func(a: int, b: list) -> int:
    pass

print(func.__annotations__)
{'a': <class 'int'>, 'b': <class 'list'>, 'return': <class 'int'>}

class annotations

class A():
    var: int

print(A.__annotations__)
{'var': <class 'int'>}

variable annotations

a: int
b: int = 2

print(__annotations__)
{'a': <class 'int'>, 'b': <class 'int'>}

intern string

s = 'hello'
s = sys.intern(s)

把字串存進快取池,相同的字串只會存一次
做字串比對會比較快且節省空間