今天又重新看了一下js,也看了之前没学的js的面向对象(之前的课缺的太多,这次花了半个小时百度了一点相关知识),突然感觉,js和lua的面向对象挺像的(lua没有对象的概念,只是用table模拟的对象,我说感觉js和lua在这点很像,可能会有很多jsor(自己编的词)会揍我(毕竟我js没看全,可能理解有误)),所以我就尝试python的dict模拟了一下js或lua的面向对象,可能是我受lua的影响,总觉的js的面向对象就是模拟的,不说了,看代码:

首先:说一下我的python方面的理解(个人见解,C语言不咋会,所以可能理解有误):
对于python,所有的变量都是C指针变量,函数也是,这也说明了我们无论存什么数据,其实存的都是指针,可以对比一下Python和C:
先看下Python:

def func(a, b): return a if a>b else b
f = func # ----------------------------------注意对比01
c = f(1, 2)  # ----------------------------------注意对比02
print(c) # ==>输出 2

再看C:

void main()
{
    int max(int, int);
    int (*p)(); 
    int c;
    
    p = max;  # ----------------------------------注意对比01
    c = (*p)(1, 2);  # ----------------------------------注意对比02
    printf("%d\n", c); // 输出 2
}
int max(int a, int b) { return a > b ? a : b;}

其实我们从下边也能看出来:

def func(a, b): return a if a>b else b
print(func) # 输出<function func at 0x00000000005FC378>此为函数地址

所以在Python中可以将函数放进字典里边,同时也能调用函数:

def func1(): pass
dic = {"func1": func1}
dic['func']()

PS:其实从这也能看出,闭包也没什么了,原理类似。
那么,我们来用dict模拟一下对象的抽象和封装:

def func1(): return 1
def func2(): return 2
def func3(): return 3

# 下边为对象(类?)的属性添加
dic["a"] = 1
dic["b"] = 2
# print(eval("func1()")) # 此为下边字典生成器的原理
dic = {("func" + str(i)):eval("func" + str(i)) for i in range(1, 4)} # 对象的方法添加

正面我们来输出一下对象dict的属性和方法:

print("a", ": ", dic["a"]) # 属性
print("b", ": ", dic["a"]) # 属性

print("dic.func1()", ": ", dic["func1"]()) # 方法
print("dic.func2()", ": ", dic["func2"]()) # 方法
print("dic.func3()", ": ", dic["func3"]()) # 方法

输出结果分别是:

a :  1
b :  1
dic.func1() :  1
dic.func2() :  2
dic.func3() :  3

也许你会说,对象还有继承和重写呢?
那我们来看看下边的:
首先定义一个function,用来模拟类:

def Classfunc(a, b, c):
    dic["a"] = a
    dic["b"] = b
    dic["c"] = c

    def func01(): return 11
    def func02(): return 22
    def func03(): return 33
    dic["func01"] = func01
    dic["func02"] = func02
    dic["func03"] = func03
    return dic # 返回一个字典,这样就能通过函数的返回值模拟创建对象了

类创建好了,现在我们来“创建对象”:cf,并输出cf的“属性”和“方法”

cf = Classfunc("aa", "bb", "cc")
print("a", ": ", cf["a"]) # 属性
print("b", ": ", cf["b"]) # 属性
print("c", ": ", cf["c"]) # 属性

print("cf.func3()", ": ", cf["func01"]()) # 方法
print("cf.func3()", ": ", cf["func02"]()) # 方法
print("cf.func3()", ": ", cf["func03"]()) # 方法

当然,我们也可以得到:

a :  aa
b :  bb
c :  cc
cf.func3() :  11
cf.func3() :  22
cf.func3() :  33

那继承和重写呢?继续看:
上边咱们写了父类ClassFunc了,下边咱们来模拟子类继承父类:

def Classfunc(d, e, sc={}): #sc-->SuperClass父类
    dic = {k: v for k, v in sc.items()} # 通过对sc的copy实现继承
    dic["d"] = d # 子类添加属性
    dic["e"] = e
    dic["a"] = "aa_重写" if sc else "aa" # 实现重写 或 增加属性

    def refunc01(): return "重写func01"
    def func01(): return "增加方法func01"
    dic["func01"] = refunc01 if sc else func01 # 实现重写 或 增加方法

    def func04(): return 44 #  "增加方法func04"
    dic["func04"] = func04
    return dic

下面我们来分别模拟有继承和无继承的情况:
无继承:

cf1 = Classfunc("dd", "ee") # 无继承
print("a", ": ", cf1["a"]) # 属性 重写了(此时的重写其实是增加属性)
try:
    print("b", ": ", cf1["b"]) # 属性b未继承
except Exception as e:
    print("属性b不存在")
try:
    print("c", ": ", cf1["c"]) # 属性c未继承
except Exception as e:
    print("属性c不存在")
print("d", ": ", cf1["d"]) # 属性
print("e", ": ", cf1["e"]) # 属性

print("cf1.func1()", ": ", cf1["func01"]()) # 方法1 重写的
# 由于try之后出现
# During handling of the above exception, another exception occurred:
# 不知道咋回事,就不try了(python没学好)
# print("cf1.func2()", ": ", cf1["func02"]()) # 方法2未继承
# print("cf1.func3()", ": ", cf1["func03"]()) # 方法3未继承
print("cf1.func4()", ": ", cf1["func04"]()) # 方法4 添加的

这时,输出结果是:

a :  aa
属性b不存在
属性c不存在
d :  dd
e :  ee
cf1.func1() :  增加方法11
cf1.func4() :  44

同样,对于有继承的:

cf2 = Classfunc("d", "e", sc=cf) # 有继承
print("a", ": ", cf2["a"]) # 属性 重写了(此时的重写其实是增加属性)
print("b", ": ", cf2["b"]) # 属性b有继承
print("c", ": ", cf2["c"]) # 属性c有继承
print("d", ": ", cf2["d"]) # 属性
print("e", ": ", cf2["e"]) # 属性

print("cf2.func1()", ": ", cf2["func01"]()) # 方法1 重写
print("cf2.func2()", ": ", cf2["func02"]()) # 方法2未继承
print("cf2.func3()", ": ", cf2["func03"]()) # 方法3未继承
print("cf2.func4()", ": ", cf2["func04"]()) # 方法

输出为:

a :  aa_重写
b :  bb
c :  cc
d :  d
e :  e
cf2.func1() :  重写func 11
cf2.func2() :  22
cf2.func3() :  33
cf2.func4() :  44

其实,通过python对字典的处理(有key时为修改,无key时为添加,和对象类似,js和lua中也是这样),我们就可以用字典(lua中叫table)(模拟类)和函数(模拟类属性和类方法的实现)来模拟出面向对象了。

也许你又双叕会问了,面向对象还有多态呢?方法的重写不就是?其他的几种就别问我了,自己思考吧,我懒得思考了。

刚刚想起来,上边的继承是单继承,如果是多继承,这样就好了:

def Classfunc(d, e, *arg_sc): #sc-->SuperClass
    dic = {}
    for d in arg_sc: # 先遍历所有父类
        for k, v in d.items():
            if not dic.has_key(k):
                dic[k] = v
    # 如果为了速度,用字典生成器则是:
    # dic = {k: v for d in arg_sc for k, v in d.items() if not dic.has_key(k)}

在想刚刚这个问题的时候,我对父类有相同方法名的继承问题有疑惑,因此手动测试了一下:

class A(object):
    def a(self):
        return "a1"
    def b1(self):
        return "b1"

class B(object):
    def a(self):
        return "a2"
    def b2(self):
        return "b2"

class C(A, B):
    def c(self):
        return "C"

a = A()
b = B()
c = C()
print(a.a()) # ==>输出 a1
print(a.b1()) # ==>输出 b1
print(b.a()) # ==>输出 a2
print(b.b2()) # ==>输出 b2
print()
print(c.a()) # 继承第一个 # ==>输出 a1
print(c.b1()) # ==>输出 b1
print(c.b2()) # ==>输出 b2
print(c.c()) # ==输出 >C

# 通过以上发现,如果子类继承的父类中有相同方法名的方法,则继承第一个继承的

最后,如果大佬们觉得我的理解有错误,请不吝赐教!谢谢!!!