...
 
Commits (2)
__pycache__
.cache
.*.sw*
def new(kind, color):
return {'kind': kind, 'color': color}
def new(kind, color):
return {'kind': kind, 'color': color}
def get(obj, attr):
return obj[attr]
def set(obj, attr, value):
obj[attr] = value
This is the start of a hand-crafted Object Oriented System using just basic Python capabilities such as modules, function calls, and dicts. It's intended to be an educational look at how an OOP system works so that you can understand it in depth. I (Zed Shaw) will slowly build the system up from basics until it's functional enough, and then potentially implement a different kind of OOP that is foreign to Python.
This repository is the one I use in the videos for the Learn Code Live OOP School series of videos.
Design Questions
=========
* All the features of OOP, OR all the features people use?
* Do we do a python style OOP, or do we do a message passing system.
* Do we need efficiency?
Answers for First Attempt
====
* Mostly the features people use.
- No MRO
* Python style OOP.
- No message passing.
* Not worry about efficiency.
Features
====
* Functions on data.
* Subclass so a missing function will look at a parent class.
* Type information.
* Define a class, and then make objects from it.
* Encapsulation
from importlib import import_module
def load_class(class_name):
cls = import_module(class_name)
assert cls, "Didn't get module '%s'" % class_name
return cls
def method(obj, name):
return obj['methods'][name]
def Class_get(obj, attr):
return obj[attr]
def Class_set(obj, attr, value):
obj[attr] = value
def new(class_name, *args, **kw):
cls = load_class(class_name)
data = cls.new(*args, **kw)
methods = {'get': cls.__dict__.get('get', Class_get),
'set': cls.__dict__.get('set', Class_set),}
obj = {'data': data,
'name': class_name,
'methods': methods}
return obj
def get(obj, attr):
get_m = method(obj, 'get')
return get_m(obj['data'], attr)
def set(obj, attr, value):
set_m = method(obj, 'set')
return set_m(obj['data'], attr, value)
def is_a(obj, class_name):
return obj['name'] == class_name
from oop import *
def test_new():
a = new("Fruit", "apple", "red")
assert is_a(a, "Fruit")
assert get(a, 'color') == "red"
assert get(a, 'kind') == "apple"
set(a, 'color', 'orange')
set(a, 'kind', 'orange')
assert get(a, 'color') == "orange"
assert get(a, 'kind') == "orange"
def test_new_class_no_getset():
b = new("Car", "buick", "green")
assert is_a(b, "Car")
assert get(b, 'color') == 'green'
assert get(b, 'kind') == 'buick'
set(b, 'color', 'red')
assert get(b, 'color') == 'red'
call(b, 'drive', 'Texas')
__pycache__
.cache
.*.sw*
from oop import *
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
def drive(self, who, where):
kind = get(self, 'kind')
color = get(self, 'color')
print(f"{who} will drive a {color} {kind} to {where}")
class Car:
def __init__(self, kind, color):
self.kind = kind
self.color = color
def drive(self, who, where):
kind = self.kind
color = self.color
print(f"{who} will drive a {color} {kind} to {where}")
from oop import *
from pprint import pprint
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
self['fresh'] = True
def _get(self, attr):
return self[attr]
def _set(self, attr, value):
self[attr] = value
def eat(self):
set(self, 'fresh', False)
def throw(self, at_who):
print(f"Throwing a {get(self, 'kind')} at {at_who}.")
This is the start of a hand-crafted Object Oriented System using just basic Python capabilities such as modules, function calls, and dicts. It's intended to be an educational look at how an OOP system works so that you can understand it in depth. I (Zed Shaw) will slowly build the system up from basics until it's functional enough, and then potentially implement a different kind of OOP that is foreign to Python.
This repository is the one I use in the videos for the Learn Code Live OOP School series of videos.
Design Questions
=========
* All the features of OOP, OR all the features people use?
* Do we do a python style OOP, or do we do a message passing system.
* Do we need efficiency?
Answers for First Attempt
====
* Mostly the features people use.
- No MRO
* Python style OOP.
- No message passing.
* Not worry about efficiency.
Features
====
* Functions on data.
* Subclass so a missing function will look at a parent class.
* Type information.
* Define a class, and then make objects from it.
* Encapsulation
from importlib import import_module
def load_class(class_name):
cls = import_module(class_name)
assert cls, "Didn't get module '%s'" % class_name
return cls
def method(self, name):
return self['methods'][name]
def Class_get(self, attr):
return self[attr]
def Class_set(self, attr, value):
self[attr] = value
def new(cls, *args, **kw):
data = {}
cls._init(data, *args, **kw)
methods = {'get': cls.__dict__.get('_get', Class_get),
'set': cls.__dict__.get('_set', Class_set),}
self = {'data': data,
'class': cls,
'methods': methods}
return self
def get(self, attr):
get_m = method(self, 'get')
return get_m(self['data'], attr)
def set(self, attr, value):
set_m = method(self, 'set')
return set_m(self['data'], attr, value)
def is_a(self, cls):
return self['class'] == cls
from oop import *
from pprint import pprint
import Car
import Fruit
def test_new():
a = new(Fruit, "apple", "red")
assert is_a(a, Fruit)
assert get(a, 'color') == "red"
assert get(a, 'kind') == "apple"
set(a, 'color', 'orange')
set(a, 'kind', 'orange')
assert get(a, 'color') == "orange"
assert get(a, 'kind') == "orange"
def test_new_class_no_getset():
b = new(Car, "buick", "green")
assert is_a(b, Car)
assert get(b, 'color') == 'green'
assert get(b, 'kind') == 'buick'
set(b, 'color', 'red')
assert get(b, 'color') == 'red'
def test_obj_methods():
b = new(Fruit, "apple", "red")
assert get(b, 'fresh') == True
Fruit.eat(b)
assert get(b, 'fresh') == False
Fruit.throw(b, 'Zed')
c = new(Car, "buick", "blue")
Car.drive(c, "Zed", "Texas")
c = Car.Car("buick", "blue")
c.drive("Zed", "Texas")
__pycache__
.cache
.*.sw*
from oop import *
import Fruit
IS_A = Fruit
def _init(self, color):
Fruit._init(self, 'apple', color)
_set = Fruit._set
_get = Fruit._get
_get_kind = Fruit._get_kind
_set_kind = Fruit._set_kind
eat = Fruit.eat
throw = Fruit.throw
from oop import *
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
def drive(self, who, where):
kind = get(self, 'kind')
color = get(self, 'color')
print(f"{who} will drive a {color} {kind} to {where}")
class Car:
def __init__(self, kind, color):
self.kind = kind
self.color = color
def drive(self, who, where):
kind = self.kind
color = self.color
print(f"{who} will drive a {color} {kind} to {where}")
class Buick(Car):
def __init__(self, color):
super().__init__('buick', color)
def park(self, where):
print(f"You are parking your buick in {where}.")
This is the start of a hand-crafted Object Oriented System using just basic Python capabilities such as modules, function calls, and dicts. It's intended to be an educational look at how an OOP system works so that you can understand it in depth. I (Zed Shaw) will slowly build the system up from basics until it's functional enough, and then potentially implement a different kind of OOP that is foreign to Python.
This repository is the one I use in the videos for the Learn Code Live OOP School series of videos.
Design Questions
=========
* All the features of OOP, OR all the features people use?
* Do we do a python style OOP, or do we do a message passing system.
* Do we need efficiency?
Answers for First Attempt
====
* Mostly the features people use.
- No MRO
* Python style OOP.
- No message passing.
* Not worry about efficiency.
Features
====
* Functions on data.
* Subclass so a missing function will look at a parent class.
* Type information.
* Define a class, and then make objects from it.
* Encapsulation
from importlib import import_module
def load_class(class_name):
cls = import_module(class_name)
assert cls, "Didn't get module '%s'" % class_name
return cls
def method(self, name):
return self['methods'][name]
def Class_get(self, attr):
return self[attr]
def Class_set(self, attr, value):
self[attr] = value
def new(cls, *args, **kw):
data = {}
cls._init(data, *args, **kw)
methods = {'get': cls.__dict__.get('_get', Class_get),
'set': cls.__dict__.get('_set', Class_set),}
self = {'data': data,
'class': cls,
'methods': methods}
return self
def get(self, attr):
cls = self['class']
get_m = cls.__dict__.get('_get_' + attr)
if get_m:
return get_m(self['data'])
else:
get_m = method(self, 'get')
return get_m(self['data'], attr)
def set(self, attr, value):
cls = self['class']
set_m = cls.__dict__.get('_set_' + attr)
if set_m:
return set_m(self['data'], value)
else:
set_m = method(self, 'set')
return set_m(self['data'], attr, value)
def is_a(self, cls):
return self['class'] == cls
from oop import *
from pprint import pprint
import Car
import Fruit
import Apple
def test_new():
a = new(Fruit, "apple", "red")
assert is_a(a, Fruit)
assert get(a, 'color') == "red"
assert get(a, 'kind') == "apple"
set(a, 'color', 'orange')
set(a, 'kind', 'orange')
assert get(a, 'color') == "orange"
assert get(a, 'kind') == "orange"
def test_new_class_no_getset():
b = new(Car, "buick", "green")
assert is_a(b, Car)
assert get(b, 'color') == 'green'
assert get(b, 'kind') == 'buick'
set(b, 'color', 'red')
assert get(b, 'color') == 'red'
def test_obj_methods():
b = new(Fruit, "apple", "red")
assert get(b, 'fresh') == True
Fruit.eat(b)
assert get(b, 'fresh') == False
Fruit.throw(b, 'Zed')
c = new(Car, "buick", "blue")
Car.drive(c, "Zed", "Texas")
c = Car.Car("buick", "blue")
c.drive("Zed", "Texas")
def test_inheritance():
a = new(Apple, 'red')
assert get(a, 'fresh') == True
assert get(a, 'kind') == 'apple'
assert get(a, 'color') == 'red'
set(a, 'color', 'green')
assert get(a, 'color') == 'green'
Apple.eat(a)
assert get(a, 'fresh') == False
Apple.throw(a, 'Zed')
__pycache__
.cache
.*.sw*
from oop import *
from pprint import pprint
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
self['fresh'] = True
def _get(self, attr):
return self[attr]
def _set(self, attr, value):
self[attr] = value
def _get_kind(self):
return self['kind']
def _set_kind(self, value):
self['kind'] = value
def eat(self):
set(self, 'fresh', False)
def throw(self, at_who):
print(f"Throwing a {get(self, 'kind')} at {at_who}.")
This is the start of a hand-crafted Object Oriented System using just basic Python capabilities such as modules, function calls, and dicts. It's intended to be an educational look at how an OOP system works so that you can understand it in depth. I (Zed Shaw) will slowly build the system up from basics until it's functional enough, and then potentially implement a different kind of OOP that is foreign to Python.
This repository is the one I use in the videos for the Learn Code Live OOP School series of videos.
Design Questions
=========
* All the features of OOP, OR all the features people use?
* Do we do a python style OOP, or do we do a message passing system.
* Do we need efficiency?
Answers for First Attempt
====
* Mostly the features people use.
- No MRO
* Python style OOP.
- No message passing.
* Not worry about efficiency.
Features
====
* Functions on data.
* Subclass so a missing function will look at a parent class.
* Type information.
* Define a class, and then make objects from it.
* Encapsulation
__pycache__
.cache
.*.sw*
from oop import *
import Fruit
def _init(self, color):
Fruit._init(self, 'apple', color)
inherits(Fruit, _init)
from oop import *
import Car
def _init(self, color):
Car._init(self, 'buick', color)
def drive(self):
print('Zed goes to Chicago always.')
inherits(Car, _init)
from oop import *
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
def drive(self, who, where):
kind = get(self, 'kind')
color = get(self, 'color')
print(f"{who} will drive a {color} {kind} to {where}")
from oop import *
from pprint import pprint
def _init(self, kind, color):
self['kind'] = kind
self['color'] = color
self['fresh'] = True
def _get(self, attr):
return self[attr]
def _set(self, attr, value):
self[attr] = value
def _get_kind(self):
return self['kind']
def _set_kind(self, value):
self['kind'] = value
def eat(self):
set(self, 'fresh', False)
def throw(self, at_who):
print(f"Throwing a {get(self, 'kind')} at {at_who}.")
from oop import *
import Apple
def _init(self):
Apple._init(self, 'green')
inherits(Apple, _init)
from importlib import import_module
import inspect
def load_class(class_name):
cls = import_module(class_name)
assert cls, "Didn't get module '%s'" % class_name
return cls
def method(self, name):
return self['methods'][name]
def Class_get(self, attr):
return self[attr]
def Class_set(self, attr, value):
self[attr] = value
def new(cls, *args, **kw):
data = {}
cls._init(data, *args, **kw)
methods = {'get': cls.__dict__.get('_get', Class_get),
'set': cls.__dict__.get('_set', Class_set),}
self = {'data': data,
'class': cls,
'methods': methods}
return self
def get(self, attr):
cls = self['class']
get_m = cls.__dict__.get('_get_' + attr)
if get_m:
return get_m(self['data'])
else:
get_m = method(self, 'get')
return get_m(self['data'], attr)
def set(self, attr, value):
cls = self['class']
set_m = cls.__dict__.get('_set_' + attr)
if set_m:
return set_m(self['data'], value)
else:
set_m = method(self, 'set')
return set_m(self['data'], attr, value)
def is_a(self, cls):
return self['class'] == cls
def inherits(parent, _init):
child = inspect.getmodule(_init)
p_dict = parent.__dict__
p_keys = p_dict.keys()
p_members = ((k, p_dict[k]) for k in p_keys if inspect.isfunction(p_dict[k]))
for key, func in p_members:
if key not in child.__dict__:
child.__dict__[key] = func
child.IS_A = parent
from oop import *
from pprint import pprint
import Car
import Fruit
import Apple
import Buick
import Grannysmith
def test_new():
a = new(Fruit, "apple", "red")
assert is_a(a, Fruit)
assert get(a, 'color') == "red"
assert get(a, 'kind') == "apple"
set(a, 'color', 'orange')
set(a, 'kind', 'orange')
assert get(a, 'color') == "orange"
assert get(a, 'kind') == "orange"
def test_new_class_no_getset():
b = new(Car, "buick", "green")
assert is_a(b, Car)
assert get(b, 'color') == 'green'
assert get(b, 'kind') == 'buick'
set(b, 'color', 'red')
assert get(b, 'color') == 'red'
def test_obj_methods():
b = new(Fruit, "apple", "red")
assert get(b, 'fresh') == True
Fruit.eat(b)
assert get(b, 'fresh') == False
Fruit.throw(b, 'Zed')
c = new(Car, "buick", "blue")
Car.drive(c, "Zed", "Texas")
def test_inheritance():
a = new(Apple, 'red')
assert get(a, 'fresh') == True
assert get(a, 'kind') == 'apple'
assert get(a, 'color') == 'red'
set(a, 'color', 'green')
assert get(a, 'color') == 'green'
Apple.eat(a)
assert get(a, 'fresh') == False
Apple.throw(a, 'Zed')
gs = new(Grannysmith)
Grannysmith.throw(gs, 'Zed')
# test that the base class and work with subclasses
Fruit.throw(gs, 'Zed')
Fruit.throw(a, 'Zed')
mycar = new(Buick, 'green')
Buick.drive(mycar)