为什么我的代码中没有自我工作

时间:2016-03-22 17:07:41

标签: python class self arcmap

我正在编写一些代码来创建一个在ArcMap中编辑地图的工具栏,并且我在使用其他类中的其他函数中获取变量值时遇到了一些问题。

所有函数都是预定义的,因此我无法更改int参数,否则代码将抛出错误。我检查了dir(),我使用self定义的变量都没有在函数中。我不认为我犯了语法错误,其他类中的代码也能正常工作。

这是我的代码:

import arcpy
import math
import pythonaddins


class findingCoordinates(object):
    """Implementation for leetScripts_addin.tool (Tool)"""

    def __init__(self):
        self.enabled = True
        self.shape = "NONE"

    def onMouseDownMap(self, x, y, button, shift):
        print "onMouseDowMap executing"
#this is where I declared the first two variables using self
        self.x = x
        self.y = y
        print "Selected point is at %r, %r" % (self.x, self.y)
        pass


class squareFeetInput(object):
    """Implementation for leetScripts_addin.combobox (ComboBox)"""
    def __init__(self):
        self.editable = True
        self.enabled = True
        #self.dropdownWidth = 'WWWWWW'
        self.width = 'WWWWWW'

    def onEditChange(self, text):
        squareFeet = text
#this is the other variable I defined that I need to use later
        self.buffDist = (math.sqrt(float(squareFeet))/2)
        print "Square size: %r ft^2 Buffer Distance: %r ft^2" % (squareFeet,self.buffDist)
        print "self.buffdist is a %r type" % self.buffDist
        return self.buffDist
        pass


class buildingTool(object):
    """Implementation for leetScripts_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        print "building tool is executing"
        #shows im_self, but no x or y
        print "%r" % dir(findingCoordinates.onMouseDownMap)  
        # Get arguments: 
        #   Input point feature class
        #   Output polygon feature class
        #   Buffer distance
        #   Boolean type: Maintain fields and field values of the input in the output 

#This is where the problem is. I can't get these values from the previous functions.

        inPoints   = (findingCoordinates.onMouseDownMap.x,findingCoordinates.onMouseDownMap.y)
        outPolys   = "U:\JackBuildingFootprints.gdb\BuildingFootprintsCopy"
        bufDist    = squareFeetInput.buffDist
        keepFields = true

        # Prepare the output based on whether field and field values are desired in the output
        #
        if keepFields:
            # Create empty output polygon feature class that includes fields of the input
            #
            arcpy.CreateFeatureClass(os.path.dirname(outPolys), os.path.basename(outPolys), "POLYGON",
                                     inPoints, "", "", inPoints)

            # Create a short list of fields to ignore when moving fields values from 
            #  input to output
            #
            ignoreFields = []

            # Use Describe properties to identify the shapeFieldName and OIDFieldName
            #
            desc = arcpy.Describe(inPoints)
            ignoreFields.append(desc.shapeFieldName)
            ignoreFields.append(desc.OIDFieldName)

            # Create a list of fields to use when moving field values from input to output
            #
            fields = arcpy.ListFields(inPoints)
            fieldList = []
            for field in fields:
                if field.name not in ignoreFields:
                    fieldList.append(field.name)
        else:
            # Create empty output polygon feature class without fields of the input
            #
            arcpy.CreateFeatureclass(os.path.dirname(outPolys), os.path.basename(outPolys), "POLYGON",
                                     "", "", "", inPoints)

        # Open searchcursor
        #
        inRows = arcpy.SearchCursor(inPoints)

        # Open insertcursor
        #
        outRows = arcpy.InsertCursor(outPolys)

        # Create point and array objects
        #
        pntObj = arcpy.Point()
        arrayObj = arcpy.Array()

        for inRow in inRows: # One output feature for each input point feature
            inShape = inRow.shape
            pnt = inShape.getPart(0)

            # Need 5 vertices for square buffer: upper right, upper left, lower left,
            #   lower right, upper right. Add and subtract distance from coordinates of
            #   input point as appropriate.
            for vertex in [0,1,2,3,4]:
                pntObj.ID = vertex
                if vertex in [0,3,4]:
                    pntObj.X = pnt.X + bufDist
                else:
                    pntObj.X = pnt.X - bufDist
                if vertex in [0,1,5]:
                    pntObj.Y = pnt.Y + bufDist
                else:
                    pntObj.Y = pnt.Y - bufDist
                arrayObj.add(pntObj)

            # Create new row for output feature
            #
            feat = outRows.newRow()

            # Shift attributes from input to output
            #
            if keepFields == "true":
                for fieldName in fieldList:
                    feat.setValue(fieldName, inRow.getValue(fieldName))

            # Assign array of points to output feature
            #
            feat.shape = arrayObj

            # Insert the feature
            #
            outRows.insertRow(feat)

            # Clear array of points
            #
            arrayObj.removeAll()

        # Delete inputcursor
        #
        del outRows



        pass

我做错了什么?这是我应该使用全局变量的极少数情况吗?为什么目录没有显示我使用self定义的变量?

修改

我不久前发了这篇文章,我只想清楚一些事情,因为我知道的更多。

第一:

这是设计用于python_add_in的代码。 Python添加根据您在设置时给出的一些参数创建一个工具栏,以及您在模板中放置的任何python代码,这些参数都是这些参数的结果。这实际上意味着上面脚本中的所有类都是在工具栏中单击或使用按钮和其他工具栏对象时发生的事件。

第二

这个问题的解决方案实际上并不在接受的答案中,我的不好。

问题的根本原因是我使用的是我在脚本中声明的类名,例如findingCoordinates。 python_add_in根据您在开始编码之前填写的模板,将这些类名称识别为它希望接收的类的名称。

考虑到这一点,问题是我试图调用就python_add_in而言并不存在的类。解决方案是继续使用类名python_add_in工具期望您使用。这些名称位于类定义下方的docstring中,因此我的findingCoordinates我应该Tool

我希望这会有所帮助。

1 个答案:

答案 0 :(得分:0)

self是指您已定义的类的实例,因此要访问这些值,您需要创建该类的实例,调用该方法,然后从中访问这些值。实例

例如:

In [9]: %paste
class findingCoordinates(object):
    """Implementation for leetScripts_addin.tool (Tool)"""

    def __init__(self):
        self.enabled = True
        self.shape = "NONE"

    def onMouseDownMap(self, x, y, button, shift):
        print "onMouseDowMap executing"
#this is where I declared the first two variables using self
        self.x = x
        self.y = y
        print "Selected point is at %r, %r" % (self.x, self.y)
        pass

## -- End pasted text --

In [10]: f = findingCoordinates()

In [11]: f.onMouseDownMap(x=1, y=2, button="button", shift="shift")
onMouseDowMap executing
Selected point is at 1, 2

In [12]: f.x
Out[12]: 1

In [13]: f.y
Out[13]: 2
编辑:您似乎对范围/命名空间也存在一些困惑。全局定义了xy;它们只存在于类实例中。这样,您还可以为该类的不同实例分别设置xy值。

In [14]: x
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-14-401b30e3b8b5> in <module>()
----> 1 x

NameError: name 'x' is not defined

In [15]: y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-009520053b00> in <module>()
----> 1 y

NameError: name 'y' is not defined

In [16]: g = findingCoordinates()

In [17]: g.onMouseDownMap(100,200,0,0)
onMouseDowMap executing
Selected point is at 100, 200

In [18]: f.x, f.y
Out[18]: (1, 2)

In [19]: g.x, g.y
Out[19]: (100, 200)