繁体   English   中英

获取“ TypeError:staticmethid不可调用”

[英]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")

一些示例可能对了解正在发生的事情很有帮助。

例子1

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

例子2

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

例子3

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM