我们可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class master: @combomethod def foo(param): param.bar() # Param could be type as well as object class slaveClass( master ): @classmethod def bar(cls): print("This is class method") slaveType = slaveClass slaveType.foo() class slaveInstance( master ): def __init__(self, data): self.data = data def bar(self): print("This is"+self.data+" method") slaveType = slaveInstance("instance") slaveType.foo() |
我的问题是,为什么默认的第一个参数不能作为comboclass的参数?或者至少,为什么我不能将object作为第一个参数传递给classmethod ?我知道classmethod和instancemethod之间的区别,也知道decorator,但是我可能不理解内置
用这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class A(object): @classmethod def print(cls): print 'A' def __print(self): print 'B' def __init__(self): self.print = self.__print a = A() a.print() A.print() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class A: def __init__(self): self.data = 'instance' @combomethod def foo(param): if isinstance(param, A): print("This is an" + param.data +" method.") elif param is A: print("This is a class method.") >>> a = A() >>> A.foo <function foo at 0x00CFE810> >>> a.foo <function foo at 0x00CFE858> >>> A.foo() This is a class method. >>> a.foo() This is an instance method. |
每次访问都是新的:
1 2 3 4 | >>> A.foo is A.foo False >>> a.foo is a.foo False |
1 2 | >>> A.foo.__code__.co_name '_wrapper' |
当从类中调用闭包时,闭包有obj == None(注意这里的self指的是combomethod,它引用了
1 2 3 4 5 | >>> print(*zip(A.foo.__code__.co_freevars, A.foo.__closure__), sep=' ') ('obj', <cell at 0x011983F0: NoneType object at 0x1E1DF8F4>) ('self', <cell at 0x01198530: combomethod object at 0x00D29630>) ('objtype', <cell at 0x00D29D10: type object at 0x01196858>) |
作为实例的属性调用时,obj为实例:
1 2 3 4 5 | >>> print(*zip(a.foo.__code__.co_freevars, a.foo.__closure__), sep=' ') ('obj', <cell at 0x01198570: A object at 0x00D29FD0>) ('self', <cell at 0x01198530: combomethod object at 0x00D29630>) ('objtype', <cell at 0x00D29D10: type object at 0x01196858>) |
这是存储在combomethod中的原始函数:
1 2 3 4 | >>> A.foo.__closure__[1].cell_contents.method <function foo at 0x00D1CB70> >>> A.foo.__closure__[1].cell_contents.method.__code__.co_name 'foo' |
1 2 3 4 | if obj is not None: return self.method(obj, *args, **kwargs) else: return self.method(objtype, *args, **kwargs) |