class A:
def self_foo(self):
pass
@staticmethod
def static_new():
pass
@classmethod
def classmethod_new(cls):
pass
When a class definition is executed, the following steps occur:
Method Resolution Order is the order in which base classes are searched for a member during lookup. See Python 2.3 Method Resolution Order for details.
from socketserver import ThreadingMixIn
from wsgiref.simple_server import WSGIServer
class ThreadingServer(ThreadingMixIn, WSGIServer):
pass
class ThreadingMixIn:
"""Mix-in class to handle each request in a new thread."""
# Decides how threads will act upon termination of the
# main process
daemon_threads = False
def process_request_thread(self, request, client_address):
"""Same as in BaseServer but as a thread.
In addition, exception handling is done here.
"""
try:
self.finish_request(request, client_address)
self.shutdown_request(request)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
def process_request(self, request, client_address):
"""Start a new thread to process the request."""
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
t.start()
ThreadingMinIn only have 2 methods, but calls 4 methods.
list(filter(lambda attr: not attr.startswith('_'), dir(WSGIServer)))
ThreadingServer.__mro__
(__main__.ThreadingServer,
socketserver.ThreadingMixIn,
wsgiref.simple_server.WSGIServer,
http.server.HTTPServer,
socketserver.TCPServer,
socketserver.BaseServer,
object)
The class body is executed (approximately) as exec(body, globals(), namespace).
A exec
demo
tmp_namespace = {
}
def say_hi():
return 'hi'
tmp_global = {
'say_hi': say_hi}
exec('a=1; b=2; hi=say_hi();print(4+5*2)', tmp_global, tmp_namespace)
print('---tmp_namespace', tmp_namespace)
# print('---tmp_global:', tmp_global)
14
---tmp_namespace {'a': 1, 'b': 2, 'hi': 'hi'}
exec(object[, globals[, locals]])
The class object is created by calling metaclass(name, bases, namespace, **kwds)
After the class object is created, it is passed to the class decorators included in the class definition (if any) and the resulting object is bound in the local namespace as the defined class.
A demo: create class object manually
def foo1(self):
print("foo1")
pass
tmp_namespace = {
'foo1':foo1, 'name': 'hi'}
FooClass=type('FooClass', (object,), tmp_namespace)
f = FooClass()
f.foo1()
print(f.name)
foo1
hi
1. object.__getattr__(self, name)
Demo
class SqliteDB:
pass
class MySqlDB:
def select(self, sql):
print('select')
def update(self, sql):
print('update')
def delete(self, sql):
print('delete')
class DBProxy:
def __init__(self, real_db):
self._real_db = real_db
print("===", self._real_db.__dict__)
def __getattr__(self, name):
return getattr(self._real_db, name)
db = DBProxy(MySqlDB())
db.select('test')
db.update('test')
db.delete('test')
=== {}
select
update
delete
2.object.__getattribute__(self, name)
3.object.__setattr__(self, name, value)
4.object.__delattr__(self, name)
5.object.__dir__(self)
object.__call__(self[, args…])
object.__len__(self)
object.__length_hint__(self)
object.__getitem__(self, key)
object.__setitem__(self, key, value)
object.__delitem__(self, key)
object.__missing__(self, key)
object.__iter__(self)
object.__reversed__(self)
object.__contains__(self, item)
(+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |).
(+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=).
…
A context manager is an object that defines the runtime context to be established when executing a with statement
Demo: python RLock implement code fragment
class RLock:
def __init__(self):
pass
def acquire(self, blocking=True, timeout=-1):
print("---fake acquire")
pass
__enter__ = acquire
def release(self):
print("---fake release")
pass
def __exit__(self, t, v, tb):
self.release()
lock = RLock()
lock.acquire()
print('Do someting')
lock.release()
---fake acquire
Do someting
---fake release
Simplifier and safer by:
with RLock():
print('Do someting')
---fake acquire
Do someting
---fake release
from contextlib import contextmanager
class RLock_A:
def __init__(self):
pass
def acquire(self, blocking=True, timeout=-1):
print("---fake acquire")
pass
def release(self):
print("---fake release")
pass
@contextmanager
def lock(self):
try:
self.acquire()
yield
finally:
self.release()
A = RLock_A()
with A.lock():
print('Do someting')
---fake acquire
Do someting
---fake release
Demo
class Student(object):
__slots__ = ('name', 'age')
s = Student()
s.name = 'Who'
s.age = 23
s.score=90
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in
----> 1 s.score=90
AttributeError: 'Student' object has no attribute 'score'
class Date:
def __init__(self, y, m, d):
self.y = y
self.m = m
self.d = d
def __repr__(self):
return '{}-{}-{}'.format(self.y, self.m, self.d)
@classmethod
def now(cls):
from datetime import datetime
now = datetime.now()
return cls(now.year, now.month, now.day)
print(Date(2008, 7, 1))
print(Date.now())
2008-7-1
2020-3-23