Skip to content

Instantly share code, notes, and snippets.

@itsjef
Last active November 25, 2016 03:08
Show Gist options
  • Select an option

  • Save itsjef/5f2c539d9e8a0ff712f0214fa634620d to your computer and use it in GitHub Desktop.

Select an option

Save itsjef/5f2c539d9e8a0ff712f0214fa634620d to your computer and use it in GitHub Desktop.
The Sublime Singleton
def singleton(cls):
instance = cls()
instance.__call__ = lambda: instance
return instance
@singleton
class A:
def __init__(self):
self.x = 10
assert A().x == 10 #1
assert A() is A() #2
A().x = 15
assert A().x == 15 #3
@itsjef

itsjef commented Nov 21, 2016

Copy link
Copy Markdown
Author

Giải thích

Hiểu về __metaclass__

Ta biết, mỗi instance là khởi tạo của một class. Vậy tương tự, mỗi class chính là instance của một metaclass.

Có thể nói: "metaclass là class của class"

Khởi tạo class từ metaclass như thế nào?

Trong Python, metaclass mặc định là type. Khi ta định nghĩa 1 class như sau:

class A: pass

đồng nghĩa với việc class A được khởi tạo như sau:

A = type('A', (), {})
# 'A' => class name
#  () => inherited classes
#  {} => class variables 

và ta khởi tạo instance của class A bằng:

a = A()

Nói thêm: Kí tự A bên trái dấu = chỉ mang nghĩa đặt tên để khởi tạo instance, không nhất thiết phải trùng với tên thật của class. Cách viết như sau không ảnh hưởng gì đến class của instance a:

i = type('A', (), {})
a = i() # => a vẫn là instance của class A
a.__class__.__name__ # => 'A'

Decorator

Là một method nhận vào một methodtrả về một method.

Ví dụ:

def wrapper(func):
    def x(a, b):
        return func(a, b)*100
    return x

@wrapper
def add(a, b):
    return a+b

add(1, 2) # => 300 

Giải thích code

def singleton(cls):
    instance = cls()
    instance.__call__ = lambda: instance
    return instance

@singleton
class A:
    def __init__(self):
        self.x = 10

Tương đương với

def singleton(cls):
    pass 

@singleton
A = type('A', (), {'x':10})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment