在 Jupyter 的多个单元格中拆分 class 函数?
Splitting class functions across multiple cells in Jupyter?
给定以下代码:
class DTC:
def __init__(self):
self.__root = None
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
如果放在 Jupyter Notebook 的单个单元格中,上面的内容将 运行。但是,如果我希望 class 代码像这样分成多个单元格,我该如何使它工作:
单元格 1
class DTC:
def __init__(self):
self.__root = None
单元格 2
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
def ent(self,Y):
freq = self.__unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
ent_ += (-p)*math.log2(p)
return ent_
在 Jupyter Notebooks 中有两种方法可以将 class 定义拆分到多个单元格
方法一
以天真的方式进行(利用继承和覆盖):
单元格 1
class DTC:
def __init__(self):
self.__root = None
Cell-2
class DTC(DTC):
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
class DTC(DTC):
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
需要注意的是,这实际上在内部创建了一个 classes 的层次结构:
import inspect
inspect.getmro(DTC)
# outputs: (__main__.DTC, __main__.DTC, __main__.DTC, object)
如果您不打算拉伸太多单元格,您可以使用此方法。
方法二
使用包jdc; more details/docs for jdc
单元格 1
import jdc # jupyter dynamic classes
class DTC:
def __init__(self):
self.__root = None
单元格 2
%%add_to DTC
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
%%add_to DTC
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
这次没有形成层次结构:
import inspect
inspect.getmro(DTC)
#output: (__main__.DTC, object)
一个python-only解决方案:
class OutsourceMethods:
@classmethod
def method(cls, f):
setattr(cls, f.__name__, f)
用作:
class A(SuperA, OutsourceMethods):
def __init__(self):
self.x = 10
@A.method
def bar(self, y):
print(self.x, y)
a = A()
a.bar(20)
> 10 20
b = A()
b.x = 3
b.bar()
> 3 20
它不等于 100%,但到目前为止我还没有注意到有什么不同。
给定以下代码:
class DTC:
def __init__(self):
self.__root = None
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
如果放在 Jupyter Notebook 的单个单元格中,上面的内容将 运行。但是,如果我希望 class 代码像这样分成多个单元格,我该如何使它工作:
单元格 1
class DTC:
def __init__(self):
self.__root = None
单元格 2
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
def ent(self,Y):
freq = self.__unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
ent_ += (-p)*math.log2(p)
return ent_
在 Jupyter Notebooks 中有两种方法可以将 class 定义拆分到多个单元格
方法一
以天真的方式进行(利用继承和覆盖):
单元格 1
class DTC:
def __init__(self):
self.__root = None
Cell-2
class DTC(DTC):
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
class DTC(DTC):
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
需要注意的是,这实际上在内部创建了一个 classes 的层次结构:
import inspect
inspect.getmro(DTC)
# outputs: (__main__.DTC, __main__.DTC, __main__.DTC, object)
如果您不打算拉伸太多单元格,您可以使用此方法。
方法二
使用包jdc; more details/docs for jdc
单元格 1
import jdc # jupyter dynamic classes
class DTC:
def __init__(self):
self.__root = None
单元格 2
%%add_to DTC
def unique(self,Y):
d = {}
for i in Y:
if i not in d:
d[i]=1
else:
d[i]+=1
return d
单元格 3
%%add_to DTC
def ent(self,Y):
freq = self.__count_unique(Y)
ent_ = 0
total = len(Y)
for i in freq:
p = freq[i]/total
entropy_ += (-p)*math.log2(p)
return ent_
这次没有形成层次结构:
import inspect
inspect.getmro(DTC)
#output: (__main__.DTC, object)
一个python-only解决方案:
class OutsourceMethods:
@classmethod
def method(cls, f):
setattr(cls, f.__name__, f)
用作:
class A(SuperA, OutsourceMethods):
def __init__(self):
self.x = 10
@A.method
def bar(self, y):
print(self.x, y)
a = A()
a.bar(20)
> 10 20
b = A()
b.x = 3
b.bar()
> 3 20
它不等于 100%,但到目前为止我还没有注意到有什么不同。