Skip to content

Instantly share code, notes, and snippets.

@DadgadCafe
Last active June 2, 2018 19:21
Show Gist options
  • Save DadgadCafe/1c4e255ae64e5e81462d2d8ddea49c3f to your computer and use it in GitHub Desktop.
Save DadgadCafe/1c4e255ae64e5e81462d2d8ddea49c3f to your computer and use it in GitHub Desktop.
# naming conventions:
# module_name, package_name, method_name, function_name, global_var_name, instance_var_name, function_parameter_name, local_var_name
# ClassName, ExceptionName
# GLOBAL_CONSTANT_NAME
*a = *range(3), #(1, 2, 3)
#################
# http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html
# 1 Unpacking
a, b, c = [1, 2, 3]
a, b, c = 1, 2, 3
a, (b, c) = 1, (2, 3)
# 2 Unpacking for swapping variables
a, b = 1, 2
a, b = b, a
# 3 Extended unpacking (Python 3 only)
a, *b, c = (1, 2, 3, 4)
b # [2, 3]
a, *b, c = [1, 2, 3, 4]
b # [2, 3]
# 4 Negative indexing
a = list(range(10))
a[-1] # 9
# 5 List slices (a[start:end])
a = list(range(10))
a[5:] # [5, 6, 7, 8, 9]
a[:5] # [0, 1, 2, 3, 4]
a[4:7] # [4, 5, 6]
# 6 List slices with negative indexing
a = list(range(10))
a[-5:] # [5, 6, 7, 8, 9]
# 7 List slices with step (a[start:end:step])
a = list(range(10))
a[1:5:2] # [1, 3]
a[::2] # [0, 2, 4, 6, 8]
# 8 List slices with negative step
a = list(range(10))
a[::-2] # [9, 7, 5, 3, 1]
# 9 List slice assignment
a = list(range(10))
a[5:6] = [0, 0] # substitute
a # [0, 1, 2, 3, 4, 0, 0, 6, 7, 8, 9]
a[1:1] = [8, 9] # add
a #[0, 8, 9, 1, 2, 3, 4, 0, 0, 6, 7, 8, 9]
a[1:-1] = [] # remove
a # [0, 9]
# 10 Naming slices (slice(start, end, step))
a = list(range(10))
s = slice(1, 5, 2)
a[s] # [1, 3]
# 11 Iterating over list index and value pairs (enumerate)
ls = ['one', 'two', 'three']
for i, v in enumerate(ls):
print('{}:{}'.format(i, v))
# 12 Iterating over dictionary key and value pairs (dict.iteritems)
d = {'a': 1, 'b': 2}
for k, v in d.items():
print('{}:{}'.format(k, v))
# 13 Zipping and unzipping lists and iterables
l1 = [1, 2, 3]
l2 = ['a', 'b', 'c']
z = zip(l1, l2) # [(1, 'a'), (2, 'b'), (3, 'c')]
zz = zip(*z) # [(1, 2, 3), ('a', 'b', 'c')]
### 14 Grouping adjacent list items using zip
a = [1, 2, 3, 4, 5, 6]
# Using iterators
group_adjacent = lambda a, k: zip(*([iter(a)] * k))
# [iter, iter, iter]; iter points to the same obj
group_adjacent(a, 3)
# [(1, 2, 3), (4, 5, 6)]
group_adjacent(a, 2)
# [(1, 2), (3, 4), (5, 6)]
group_adjacent(a, 1)
# [(1,), (2,), (3,), (4,), (5,), (6,)]
# Using slices
from itertools import islice
group_adjacent = lambda a, k: zip(*(islice(a, i, None, k) for i in range(k)))
group_adjacent(a, 3)
# [(1, 2, 3), (4, 5, 6)]
group_adjacent(a, 2)
# [(1, 2), (3, 4), (5, 6)]
group_adjacent(a, 1)
# [(1,), (2,), (3,), (4,), (5,), (6,)]
### 15 Sliding windows (n-grams) using zip and iterators
from itertools import islice
def n_grams(a, n):
z = (islice(a, i, None) for i in range(n))
return zip(*z)
a = [1, 2, 3, 4, 5, 6]
n_grams(a, 3)
# [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)]
n_grams(a, 2)
# [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
n_grams(a, 4)
# [(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6)]
# 16 Inverting a dictionary using zip
m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
dict(zip(m.values(), m.keys()))
# 17 Flattening lists:
import itertools
a = [[1, 2], [3, 4], [5, 6]]
list(itertools.chain.from_iterable(a))
sum(a, [])
[i for x in a for i in x]
# 18 Generator expressions
(i for i in range(10))
# 19 Dictionary comprehensions
{i: i for i in range(5)}
# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
# 20 Inverting a dictionary using a dictionary comprehension
m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
{v:k for k,v in m.items()}
# 21 Named tuples (collections.namedtuple)
Point = collections.namedtuple('Point', ['x', 'y'])
p = Piont(x=1, y=2)
p.x
# 22 Inheriting from named tuples:
class Point(collections.namedtuple('PointBase', ['x', 'y'])):
__slots__ = ()
def __add__(self, other):
return Point(x = self.x + other.x,
y = self.y + other.y)
p1 = Point(x=1, y=2)
p2 = Point(x=1, y=2)
p3 = p1 + p2
# 23 Sets and set operations
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s1 & s2
s1 | s2
s1 - s2
s1 ^ s2 # (A ^ B) == ((A - B) | (B - A))
# 24 Multisets and multiset operations (collections.Counter)
A = collections.Counter([1, 2, 2])
# Counter({1: 1, 2: 2})
B = collections.Counter([2, 2, 3])
# Counter({2: 2, 3: 1})
A | B
A & B
A + B
A - B
# 25 Most common elements in an iterable (collections.Counter)
A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7])
# Counter({1: 2, 2: 2, 3: 4, 4: 1, 5: 1, 6: 1, 7: 1})
A.most_common(1)
# [(3, 4)]
# 26 Double-ended queue (collections.deque)
Q = collections.deque()
Q.append(1)
Q.appendleft(2)
Q.extend([3, 4])
Q.extendleft([5, 6])
Q # deque([6, 5, 2, 1, 3, 4])
Q.pop()
Q.popleft()
Q.rotate(3)
# 27 Double-ended queue with maximum length (collections.deque)
last_three = collections.deque(maxlen=3)
for i in range(10):
last_three.append(i)
print(', '.join(str(x) for x in last_three))
# 28 Ordered dictionaries (collections.OrderedDict)
m = dict((str(x), x) for x in range(10))
print(', '.join(m.keys()))
# 1, 0, 3, 2, 5, 4, 7, 6, 9, 8
m = collections.OrderedDict((str(x), x) for x in range(10))
print(', '.join(m.keys()))
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
m = collections.OrderedDict((str(x), x) for x in range(10, 0, -1))
print(', '.join(m.keys()))
# 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
# 29 Default dictionaries (collections.defaultdict)
d = dict()
m['a'] # error
m = collections.defaultdict(int)
m['a'] # 0
m['b'] # 0
m = collections.defaultdict(str)
m['a'] # ''
m['b'] += 'a'
m['b'] # 'a'
m = collections.defaultdict(lambda: '[default value]')
m['a'] # '[default value]'
# 30 Using default dictionaries to represent simple trees
import json
tree = lambda: collections.defaultdict(tree)
root = tree() # f
root['menu']['id'] = 'file'
root['menu']['value'] = 'File'
root['menu']['menuitems']['new']['value'] = 'New'
root['menu']['menuitems']['new']['onclick'] = 'new();'
root['menu']['menuitems']['open']['value'] = 'Open'
root['menu']['menuitems']['open']['onclick'] = 'open();'
root['menu']['menuitems']['close']['value'] = 'Close'
root['menu']['menuitems']['close']['onclick'] = 'close();'
print(json.dumps(root, sort_keys=True, indent=4, separators=(',', ': ')))
# 31 Mapping objects to unique counting numbers (collections.defaultdict)
import itertools, collections
def f():
t = itertools.count()
return lambda: next(t)
value_to_numeric_map = collections.defaultdict(f())
value_to_numeric_map['a'] # 0
value_to_numeric_map['b'] # 1
value_to_numeric_map['c'] # 2
value_to_numeric_map['a'] # 0
value_to_numeric_map['b'] # 1
# 32 Largest and smallest elements (heapq.nlargest and heapq.nsmallest)
[random.randint(0, 100) for _ in range(100)]
heapq.nsmallest(5, a)
heapq.nlargest(5, a)
# 33 Cartesian products (itertools.product)
# 34 Combinations and combinations with replacement (itertools.combinations and itertools.combinations_with_replacement)
for c in itertools.combinations([1, 2, 3, 4, 5], 3):
print(''.join(str(x) for x in c))
for c in itertools.combinations_with_replacement([1, 2, 3], 2):
print(''.join(str(x) for x in c))
# 35 Permutations (itertools.permutations)
for p in itertools.permutations([1, 2, 3, 4]):
print(''.join(str(x) for x in p))
# 36 Chaining iterables (itertools.chain)
a = [1, 2, 3, 4]
for p in itertools.chain(itertools.combinations(a, 2),
itertools.combinations(a, 3)):
print(p)
# 37 Grouping rows by a given key (itertools.groupby)
# 38 Start a static HTTP server in any directory
# python -m SimpleHTTPServer 5000
# 39 Learn the Zen of Python
import this
# 40 Use C-Style Braces Instead of Indentation to Denote Scopes
from __future__ import braces
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# # octothrope, pound character
ord('A') # 65
chr(65) # 'A'
print('%d' % 123)
print('%r' % False) # %r for debugging
print('%s' % False)
print('%s' % '123')
# array append insert pop
# dict
dt = {'a': 1, 'b': 2}
dt.get('a', 'default')
dt['a']
if 'a' in dt
dt.pop('a')
# set
st = {1, 2, 3}
st2 = set([3, 4, 5])
st & st2
st | st2
st.add(5)
st.remove(5)
# func
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
def f(*args, **kwargs):
print(args, kwargs)
f(1, 2, a=3, b=4)
f(*[1], **{'a':1})
# slice
ls = [1, 2, 3]
ls[1:] # [2, 3]
ls[:2] # [1, 2]
ls[1:2] # [2a]
ls[:-1] # [1, 2]
L = list(range(10))
# copy list
ls[:]
L[:5:2] # [0, 2, 4]
L[::5] # [0, 5]
## iteration
for k in dict
print(k)
for v in dict.values()
print(v)
for k, v in dict.items()
print(k, v)
from collections import Iterable
isinstance('abc', Iterable) # True
for (i, v) in enumerate([1, 2, 3]):
print(i, v)
for (a, b) in [(1, 2), (3, 4)]:
print(a, b)
## list comprehension
[x*y for x in range(5) for y in range(5)]
## generator
(x*y for x in range(5) for y in range(5))
def g(max):
i = 0
while i <= max:
yield i
i += 1
return 'DONE'
g5 = g(5)
while True:
try:
ret = next(g5)
print(ret)
except StopIteration as e:
print(e.value)
break
## diff Iterable Iterator
iter([1, 2, 3]) # Iterable to Iterator
## HOF
def f():
a = 5
def ff():
nonlocal a
a += 1
print(a)
ff()
print(a)
## functools partial
import functools
int2 = functools.partial(int, base=2)
## module
# pkg
# __init__.py
# xx.py
# yy.py
import pkg
import pkg.xx
## class
class Animal():
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name):
super().__init__(name)
# super(self.__class__, self).__init__(name)
# Animal.__init__(self, name)
hasattr()
getattr()
# slots
class Student(object):
__slots__ = ('name', 'age')
# getter setter @property decorator
class Student(object):
def __init__(self, score):
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self.__score = value
__str__
__repr__
__iter__
__next__
__getitem__
__getattr__
__call__
def Fib():
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > 10000:
raise StopIteration()
else:
return self.a
def __getitem__(self, n):
if isinstance(n, int): # n是索引
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice): # n是切片
start = n.start
stop = n.stop
if start is None:
start = 0
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
__repr__ = __str__
Chain().status.user.timeline.list # '/status/user/timeline/list'
# enum
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
from enum import Enum, unique
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
# type
# 动态创建 class; 实际上,class 也是通过 type 创建
def fn(self, name='non'):
print(name)
C = type('C', (object,), dict(fn=fn)) # name; tuple of superclass; dict of attrs
c = C()
c.fn()
# metaclass usage:ORM
# metaclass是类的模板,所以必须从`type`类型派生:
class ListMetaclass(type):
def __new__(cls, name, bases, attrs): # 当前准备创建的类的对象; 类的名字; 类继承的父类集合; 类的方法集合
attrs['add'] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs)
class MyList(list, metaclass=ListMetaclass):
pass
L = MyList()
L.add(1)
## with
class WithClass:
def __init__(self):
print('__init__')
def __enter__(self):
print('__enter__')
def __exit__(self, exe_type, exe_value, traceback):
print('__exit__')
print(exe_type)
print(exe_value)
print(traceback)
return True # supress exception
def __repr__(self):
print('with class obj')
with WithClass() as o:
print(f'do something with {o}')
raise Exception('error occurs')
print('all done')
from contextlib import contextmanager
@contextmanager
def manage_file():
try:
print('__enter__')
yield
finally:
print('__exit__')
@contextmanager
def manage_file(name):
try:
f = open(name)
yield f
finally:
f.close()
with manage_file('test.txt') as f:
f.read()
## io
with open('/path/to/file', 'r') as f:
print(f.read())
try:
f = open('/..', r)
print(f.read())
finally:
if f:
f.close()
for line in f.readlines():
print(line.strip())
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
f.close()
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
f.read() # blabla..
f.read() # nothing... cursor at end..
f.seek(0) # move cursor back to 0
f.read() # blabla
f.tell() # where is cursor
f.readline() # read a line, cursor to next line
f.readlines() # read all line, store to array
# pickle
import pickle
f = open('dump.txt', 'wb')
pickle.dump('teststests', f)
f.close()
f = open('dump.txt', 'rb')
d = pickle.load(f)
f.close()
with open('dump.txt', 'wb') as f:
pickle.dump(d, f)
# json
import json
d = dict(name='Bob', age=20, score=88)
json.dumps(d) # '{"age": 20, "score": 88, "name": "Bob"}'
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
d = json.loads(json_str) # {'age': 20, 'score': 88, 'name': 'Bob'}
# dump class to json format
json.dumps(s, default=lambda obj: obj.__dict__)
json.loads(json_str, object_hook=lambda d: Cls(**d))
## misc
import types
types.FunctionType #...
import sys
sys.path # view system path
sys.path.append('/Users/michael/my_py_scripts')# 运行时修改路径
"." * 10
a, b, c = [1, 2, 3]
d, e, f = (4, 5, 6)
from sys import argv
a, b, c, d = argv
def id(*all):
return all #tuple
## generic function
class C(object):
def foo(self):
pass
C().foo # bound
C.foo # unbound
C.__dict__['foo'].__get__(None, C)
C.__dict__['foo'].__get__(c, C)
# namedtulpe <= tuple
# magic method
## def func
class People(object):
'''Silly Person'''
## ??? not working in py3,
## refact print in decorator
def __new__(cls, *args, **kwargs):
print('__new__ called.')
return super(People, cls).__new__(cls, *args, **kwargs)
def __init__(self, name, age):
print('__init__ called.')
self.name = name
self.age = age
def __str__(self):
return 'PERSON: %s %s' % (self.name, self.age)
## decorator
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('before %s():' % func.__name__)
ret = func(*args, **kw)
print('after %s():' % func.__name__)
return ret
return wrapper
# custom decorator log; works with @log and @log('DEBUG')
def log(mode):
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s: before %s():' % mode func.__name__)
ret = func(*args, **kw)
print('%s: after %s():' % mode func.__name__)
return ret
return wrapper
if isinstance(mode, str):
return log
else:
fn = mode
mode = 'DEFAULT'
return log(fn)
class P():
'''Silly Person'''
@log
def __f(self):
pass
@staticmethod
@log
def __F():
pass
@log
def f(self):
self.__f()
# self.__F()
P.__F()
@log
def __init__(self):
pass
####################
class PositiveInteger(int):
def __init__(self, value):
super(PositiveInteger, self).__init__(self, abs(value))
i = PositiveInteger(-3)
print i
=>
class PositiveInteger(int):
def __new__(cls, value):
return super(PositiveInteger, cls).__new__(cls, abs(value))
i = PositiveInteger(-3)
print i
## 实现单例模式
class Singleton(object):
def __new__(cls):
# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
obj1 = Singleton()
obj2 = Singleton()
obj1.attr1 = 'value1'
print obj1.attr1, obj2.attr1
print obj1 is obj2
#########
class Movie(object):
def __init__(self, title, description, score):
self.title = title
self.description = description
self.score = score
     self.ticket = ticket
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < 0:
raise ValueError("Negative value not allowed:{}".format(score))
self.__score = score
@score.deleter
def score(self):
raise AttributeError("Can not delete score")
=>
class Integer(object):
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if value < 0:
raise ValueError("Negative value not allowed")
instance.__dict__[self.name] = value
class Movie(object):
score = Integer('score')
ticket = Integer('ticket')
=>
class Integer(object):
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
if value < 0:
raise ValueError('Negative value not allowed')
instance.__dict__[self.name] = value
class Movie(object):
score = Integer('score')
ticket = Integer('ticket')
def __init__(self, title, description, score, ticket):
self.title = title
self.description = description
self.score = score
self.ticket = ticket
#############
from collections import Counter
l = ['a', 'b', 'c', 'a']
Counter(l)
#############
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDeck():
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks
suit in self.suits]
def __len__(self):
return len(self.cards)
def __getitem__(self, position):
return self._cards[position]
deck = FrenchDeck()
len(deck)
deck[0]
decl[-1]
from random import choice
choice(deck)
## asyncio
import asyncio
@asyncio.coroutine
def hello():
print('hello ')
r = yield from asyncio.sleep(1)
print('world')
# async await
async def hello():
print("Hello world!")
r = await asyncio.sleep(1)
print("Hello again!")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
import threading
import asyncio
@asyncio.coroutine
def hello():
print('Hello world! (%s)' % threading.currentThread())
yield from asyncio.sleep(1)
print('Hello again! (%s)' % threading.currentThread())
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
import asyncio
@asyncio.coroutine
def wget(host):
print('wget %s...' % host)
connect = asyncio.open_connection(host, 80)
reader, writer = yield from connect
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
writer.write(header.encode('utf-8'))
yield from writer.drain()
while True:
line = yield from reader.readline()
if line == b'\r\n':
break
print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
# Ignore the body, close the socket
writer.close()
async def wget(host):
print('wget %s...' % host)
connect = asyncio.open_connection(host, 80)
reader, writer = await connect
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
writer.write(header.encode('utf-8'))
await writer.drain()
while True:
line = await reader.readline()
if line == b'\r\n':
break
print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
# Ignore the body, close the socket
writer.close()
loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
import threading
from functools import wraps
def delay(delay = 0):
'''
Decorator delaying the execution of a function for a while.
'''
def wrap(f):
@wraps(f)
def delayed(*args, **kwargs):
timer = threading.Timer(delay, f, args=args, kwargs=kwargs)
timer.start()
return delayed
return wrap
from utils import delay
@delay(3)
def my_func(*args):
print(args)
if __name__ == '__main__':
my_func('Hello', 'world')
type('Bar', (object,), {'spam': 'eggs'})
class MetaClass(type):
def __init__(cls, name, bases, attrs):
print('Defining %s' % cls)
print('Name: %s' % name)
print('Bases: %s' % (bases,))
print('Attributes:')
for (name, value) in attrs.items():
print(' %s: %r' % (name, value))
class RealClass(object, metaclass=MetaClass):
spam = 'eggs'
class SubClass(RealClass): # Notice there's no metaclass here.
pass
class Multipler():
def __init__(self, n):
self.n = n
def __call__(self, m):
return self.n * m
def multiple(n):
return lambda m: m*n
class FakeDict():
def __init__(self):
# prevent setattr
self.__dict__['_d'] = {}
# intercept .
def __getattr__(self, k):
print('accessing getattr', k)
if k in self._d:
return self._d[k]
# intercept . assign value
def __setattr__(self, k, v):
print('accessing setattr', k, v)
self._d[k] = v
# in
def __contains__(self, k):
print('accessing contain', k)
return k in self._d
# intercept []
def __getitem__(self, k):
print('accessing getitem', k)
if k in self._d:
return self._d[k]
return None
# intercept [] assign value
def __setitem__(self, k, v):
print('accessing setitem', k, v)
self._d[k] = v
d = FakeDict()
d.a = 5 #accessing setattr a 5
d.a #accessing getattr a 5
d['a'] #accessing getitem a 5
d['a'] = 10 #accessing setitem a 10
d.a
d.__dict__ #{'_d': {'a': 10}}
class C():
def __init__(self):
pass
def f(self):
print('self f')
def f():
print('f')
@staticmethod
def f():
print('static f')
C().f() # staic => f => self
class C():
a = 4
def __init__(self):
self.a = 5
C().f() # call C.f then c.f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment