![](/img/trans.png)
[英]getting TypeError: 'TextDetector' object is not callable
[英]Getting “TypeError: with staticmethid not callable”
我收到有关TypeError的错误:'staticmethod'对象不可调用。 基本上,您的输入是一个映射,并且假设您提供一对浮点数(pt,eta),则代码应返回特定值所属的bin的Y值。
我试过相关线程(可能重复),但似乎并没有得到我要找的答案。
当然,如果有人对如何改进代码提出任何建议,那当然会受到欢迎。
import ROOT as root
import sys,math
class SFs():
global etaBinsH
global get_EfficiencyData
global get_EfficiencyMC
global eff_dataH
global eff_mcH
global get_ScaleFactor
@staticmethod
def ScaleFactor(inputRootFile) :
#inputRootFile="Muon_IsoMu27.root"
eff_dataH = root.std.map("string", root.TGraphAsymmErrors)()
eff_mcH = root.std.map("string", root.TGraphAsymmErrors)()
#std::map<std::string, root.TGraphAsymmErrors *> eff_data
#std::map<std::string, root.TGraphAsymmErrors *> eff_mc
EtaBins=["Lt0p9", "0p9to1p2","1p2to2p1","Gt2p1"]
print inputRootFile
fileIn = root.TFile(inputRootFile,"read")
fileIn.ls()
HistoBaseName = "ZMassEta"
etaBinsH = fileIn.Get("etaBinsH")
#etaLabel, GraphName
nEtaBins = int(etaBinsH.GetNbinsX())
eff_data= []
eff_mc= []
#eff_mcH =root.TGraphAsymmErrors()
print "EtaBins...........",nEtaBins, len(EtaBins)
for iBin in range (0, nEtaBins) :
etaLabel = EtaBins[iBin]
GraphName = HistoBaseName+etaLabel+"_Data"
print GraphName,etaLabel
eff_data.append(fileIn.Get(str(GraphName)))
eff_dataH[etaLabel]=fileIn.Get(str(GraphName))
GraphName = HistoBaseName+etaLabel+"_MC"
eff_mc.append(fileIn.Get(str(GraphName)))
eff_mcH[etaLabel]=fileIn.Get(str(GraphName))
print eff_mcH[etaLabel].GetXaxis().GetNbins()
print eff_mcH[etaLabel].GetX()[5]
sff = get_ScaleFactor(46.8,2.0)
print "SFFFFFFFFFFFFFf",sff
@staticmethod
def get_ScaleFactor(pt, eta) :
efficiency_data = get_EfficiencyData(pt, eta)
efficiency_mc = get_EfficiencyMC(pt, eta)
if efficiency_mc != 0. :
SF = float(efficiency_data)/float(efficiency_mc)
else :
SF=1.
print "ScaleFactor::get_ScaleFactor(double pt, double eta) Scale Factor set to",SF,efficiency_data,efficiency_mc
return SF
@staticmethod
def get_EfficiencyMC(pt, eta) :
label = FindEtaLabel(eta,"mc")
#label= "Lt0p9"
binNumber = etaBinsH.GetXaxis().FindFixBin(eta)
label = etaBinsH.GetXaxis().GetBinLabel(binNumber)
ptbin = FindPtBin(eff_mcH, label, pt)
Eta = math.fabs(eta)
print "eff_mcH ==================",eff_mcH,binNumber,label,ptbin
#ptbin=10
if ptbin == -99 : eff =1
else : eff= eff_mcH[label].GetY()[ptbin-1]
if eff > 1. : eff = -1
if eff < 0 : eff = 0.
print "inside eff_mc",eff
return eff
@staticmethod
def get_EfficiencyData(pt, eta) :
label = FindEtaLabel(eta,"data")
#label= "Lt0p9"
binNumber = etaBinsH.GetXaxis().FindFixBin(eta)
label = etaBinsH.GetXaxis().GetBinLabel(binNumber)
print eff_dataH
ptbin = FindPtBin(eff_dataH, label, pt)
Eta = math.fabs(eta)
fileOut=root.TFile("out.root","recreate")
fileOut.cd()
eff_dataH[label].Write(label)
#ptbin=10
if ptbin == -99 : eff =1
else : eff= eff_dataH[label].GetY()[ptbin-1]
print "inside eff_data",eff
if eff > 1. : eff = -1
if eff < 0 : eff = 0.
print "inside eff_data",eff,pt,eta,label
return eff
@staticmethod
def FindPtBin( eff_map, EtaLabel, Pt) :
Npoints = eff_map[EtaLabel].GetN()
print Npoints, "for ===============>",eff_map[EtaLabel],eff_map[EtaLabel].GetN(),EtaLabel
#ptMAX=100
#ptMIN=90
ptMAX = (eff_map[EtaLabel].GetX()[Npoints-1])+(eff_map[EtaLabel].GetErrorXhigh(Npoints-1))
ptMIN = (eff_map[EtaLabel].GetX()[0])-(eff_map[EtaLabel].GetErrorXlow(0))
if Pt >= ptMAX : return Npoints
elif Pt < ptMIN :
return -99
else : return eff_map[EtaLabel].GetXaxis().FindFixBin(Pt)
@staticmethod
def FindEtaLabel(Eta, Which) :
Eta = math.fabs(Eta)
binNumber = etaBinsH.GetXaxis().FindFixBin(Eta)
EtaLabel = etaBinsH.GetXaxis().GetBinLabel(binNumber)
it=-1
if str(Which) == "data" :
it = eff_dataH.find(EtaLabel)
if str(Which) == "mc" :
it = eff_mcH.find(EtaLabel)
return EtaLabel
sf = SFs()
sff = sf.ScaleFactor("Muon_IsoMu27.root")
一些示例可能对了解正在发生的事情很有帮助。
class RandomClass():
global global_function
@staticmethod
def random_function(input):
print(global_function("test"))
return "random_function({})".format(input)
@staticmethod
def global_function(input):
return "global_function({})".format(input)
rc = RandomClass()
print(rc.random_function("Input!"))
输出
Traceback (most recent call last):
File "test.py", line 14, in <module>
print(rc.random_function("Input!"))
File "test.py", line 6, in random_function
print(global_function("test"))
TypeError: 'staticmethod' object is not callable
class RandomClass():
@staticmethod
def random_function(input):
print(global_function("test"))
return "random_function({})".format(input)
@staticmethod
def global_function(input):
return "global_function({})".format(input)
rc = RandomClass()
print(rc.random_function("Input!"))
产量
Traceback (most recent call last):
File "test.py", line 12, in <module>
print(rc.random_function("Input!"))
File "test.py", line 4, in random_function
print(global_function("test"))
NameError: global name 'global_function' is not defined
class RandomClass():
@staticmethod
def random_function(input):
print(RandomClass.global_function("test")) # Notice change here.
return "random_function({})".format(input)
@staticmethod
def global_function(input):
return "global_function({})".format(input)
rc = RandomClass()
print(rc.random_function("Input!"))
产量
global_function(test)
random_function(Input!)
简而言之, @staticmethod
方法无法访问其this
函数(无论是使用this
还是global
定义),而必须初始化一个新的独立类以调用其所在类中的函数(示例3)。 正如@ C.Nivs所提到的,您也许应该研究一下根本不使用类。
通过不将所有方法都设为static
,可以使@Felipe的答案更轻松一点,您可以消除global
声明共享变量的需要,因为这始终是您正在做的事情:
class SFs():
def __init__(self):
# initialize your global vars instead as
# instance variables
self.etaBinsH = None
self.get_EfficiencyData = None
self.get_EfficiencyMC = None
self.eff_dataH = None
self.get_ScaleFactor = None
# don't make this static, then you have access to the self attributes and it makes
# your code a bit more explicit
def scale_factor(self, input_file):
self.eff_dataH = root.std.map("string", root.TGraphAsymmErrors)()
self.eff_mcH = root.std.map("string", root.TGraphAsymmErrors)()
EtaBins = ["Lt0p9", "0p9to1p2","1p2to2p1","Gt2p1"]
print(input_file) # print with parentheses makes this more portable between versions
fileIn = root.TFile(input_file, "read")
# Now you can use this through self, which is more pythonic
self.etaBinsH = fileIn.Get("etaBinsH")
nEtaBins = int(self.etaBinsH.GetNbinsX())
eff_data, eff_mc = [], []
# rest of code
然后,可以通过self
共享变量,也可以通过self
来访问函数,否则staticmethod
会将self
访问限制在函数之外,这就是为什么您不能调用任何其他函数的原因。
类是名称空间,而self
允许您将变量绑定到实例级名称空间。 通过使用global
,您试图将这些变量推回全局名称空间以在周围共享它们,实际上,您实际上已经可以访问名称空间以共享这些变量!
作为一个简单的例子:
class A:
# here is the namespace for the *class* A
x = 0 # x is an attribute on the class A, it is accessible on the class and instance level
def __init__(self):
self.y = 4 # y is now explicitly tied to an instance of A, and can be shared between *instance* methods of A
def use_y(self):
# because this is non-static, I have access to instance level
# variables, this is how you share them!
print(self.y)
# I also have access to class-level attributes
print(self.x)
@staticmethod
def use_x():
# I don't have access to self.y, because staticmethod takes that away
try:
print(self.y)
except NameError:
print("Couldn't make this work")
print(A.x) # have to print this as a *class-level* attribute, because self isn't defined here
a = A()
a.use_y()
# 4
# 0
a.use_x()
# Couldn't make this work
# 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.