【问题标题】:Monkey patch failing on __init__ statement__init__ 语句上的猴子补丁失败
【发布时间】:2021-03-25 08:42:45
【问题描述】:

我正在尝试修补 clodsa 包中的增强函数以读取自定义命名的 .json 文件,而不是遵循它们的格式,因此而不是 /annotations.json 生成 new_name.json:

!pip install clodsa
??augmentor

Type:        COCOLinearInstanceSegmentationAugmentor
String form: <clodsa.augmentors.cocoLinearInstanceSegmentationAugmentor.COCOLinearInstanceSegmentationAugmentor object at 0x7fbc1f48de50>
File:        /usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py
Source:     
class COCOLinearInstanceSegmentationAugmentor(IAugmentor):

    def __init__(self, inputPath, parameters):
        IAugmentor.__init__(self)
        self.imagesPath = inputPath
        self.annotationFile = inputPath + "/annotations.json"
        # output path represents the folder where the images will be stored
        if parameters["outputPath"]:
            self.outputPath = parameters["outputPath"]
        else:
            raise ValueError("You should provide an output path in the parameters")
        
        self.ignoreClasses = parameters.get("ignoreClasses",set())



    def readImagesAndAnnotations(self):
        (self.info, self.licenses, self.categories, self.dictImages, self.dictAnnotations) \
            = readCOCOJSON(self.annotationFile)

我尝试了以下方法来修补 self.annotationFile 路径:

def new_init(self, inputPath, parameters):
  IAugmentor.__init__(self)
  self.imagesPath = inputPath
  self.annotationFile = inputPath + "/new_name.json"
  # output path represents the folder where the images will be stored
  if parameters["outputPath"]:
    self.outputPath = parameters["outputPath"]
  else:
    raise ValueError("You should provide an output path in the parameters")

  self.ignoreClasses = parameters.get("ignoreClasses",set())

augmentor.__init__ = new_init

当我运行新的 init 时,它确实显示猴子用 ??augmentor 修补了 init。init

但是当我运行完整的代码时,它只是回退到使用旧的 init 语句:

---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

<ipython-input-15-30ca2128bdb6> in <module>()
      1 #Perform the augmentations
----> 2 augmentor.applyAugmentation()

2 frames

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py in applyAugmentation(self)
     87 
     88     def applyAugmentation(self):
---> 89         self.readImagesAndAnnotations()
     90 
     91         newannotations = Parallel(n_jobs=-1)(delayed(readAndGenerateInstanceSegmentation)

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/cocoLinearInstanceSegmentationAugmentor.py in readImagesAndAnnotations(self)
     84     def readImagesAndAnnotations(self):
     85         (self.info, self.licenses, self.categories, self.dictImages, self.dictAnnotations) \
---> 86             = readCOCOJSON(self.annotationFile)
     87 
     88     def applyAugmentation(self):

/usr/local/lib/python3.7/dist-packages/clodsa/augmentors/utils/readCOCOJSON.py in readCOCOJSON(jsonPath)
      5 
      6 def readCOCOJSON(jsonPath):
----> 7     with open(jsonPath) as f:
      8         data = json.load(f)
      9 

FileNotFoundError: [Errno 2] No such file or directory: '/content/drive/annotations.json'

我做错了什么?

【问题讨论】:

  • 您是否要修补类的实例

标签: python function class monkeypatching image-augmentation


【解决方案1】:

我查看了source code for the COCOLinearInstanceSegmentationAugmentor class(这个项目的存储库有点乱——他们提交了二进制.pyc 文件和其他杂乱无章的文件,但这是一个旁白……)

看起来你应该能够简单地通过子类化来做到这一点:

class MyCOCOLinearInstanceSegmentationAugmentor(COCOLinearInstanceSegmentationAugmentor):
    def __init__(self, inputPath, parameters):
        super().__init__(inputPath, parameters)
        self.annotationFile = os.path.join(inputPath, 'new_name.json')

或者,由于self.annotationsFile 只是一个普通属性,在COCOLinearInstanceSegmentationAugmentor 被实例化之后,但在调用任何使用此属性的方法之前,您可以简单地为其分配一个新值,例如:

augmentor.annotationFile = <whatever you want>

【讨论】:

  • 感谢您的帮助。第二种解决方案有效、实用且优雅!
  • 不幸的是,第一个解决方案不起作用:NameError: name 'COCOLinearDetectionAugmentor' is not defined
  • 看来我误读了您的原始问题,您想要COCOLinearInstanceSegmentationAugmentor 而不是COCOLinearDetectionAugmentor。尽管如此,答案还是一样的。在任何一种情况下,如果您想将其子类化,您都需要 import 类:from closda.augmentators import COCOLinearInstanceSegmentationAugmentor
猜你喜欢
  • 2015-09-03
  • 2019-09-07
  • 2016-09-01
  • 2012-09-16
  • 2012-12-18
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多