为什么不能在我的代码中自我工作
Why isn't self working in my code
我正在编写一些代码来创建一个在 ArcMap 中编辑地图的工具栏,但我在从我正在使用的其他 classes 中的其他函数获取变量值时遇到了一些问题。
所有函数都是预定义的,所以我不能更改 int
参数,否则代码会抛出错误。我检查了函数中使用 self
定义的变量的 dir()
和 none。我不认为我犯了语法错误,其他 classes 中的代码工作正常。
这是我的代码:
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
定义的变量?
编辑:
我不久前做了这个 post,现在我知道的更多了,我只是想澄清一些事情。
第一个:
这是设计用于 python_add_in 的代码。 Python 插件根据您在设置时给它的一些参数创建一个工具栏,以及您放入模板中的任何 python 代码,它都会根据这些参数生成。这实质上意味着上面脚本中的所有 classes 都是在单击或使用工具栏中的按钮和其他工具栏对象时发生的事件。
第二个:
这个问题的解决方案实际上不在公认的答案中,我的错。
问题的根本原因是我使用了我在脚本中声明的 class 名称,例如 findingCoordinates
。 python_add_in 不会将这些 class 名称识别为它希望根据您在开始编码之前填写的模板接收的 classes 的名称。
考虑到这一点,问题是我试图调用 class 就 python_add_in 而言根本不存在的 es。解决方案是继续使用 class 名称 python_add_in 工具希望您使用。这些名称位于 class 定义下方的文档字符串中,因此在我有 findingCoordinates
的地方我应该有 Tool
.
希望对您有所帮助。
self
指的是您定义的 class 的实例,因此要访问这些值,您需要创建 class 的实例,调用方法,然后访问实例中的值。
例如:
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
编辑:您似乎也对 scoping/namespaces 感到困惑。没有全局定义 x
或 y
;它们只存在于 class 个实例中。这也将允许您为 class.
的不同实例设置单独的 x
和 y
值
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)
我正在编写一些代码来创建一个在 ArcMap 中编辑地图的工具栏,但我在从我正在使用的其他 classes 中的其他函数获取变量值时遇到了一些问题。
所有函数都是预定义的,所以我不能更改 int
参数,否则代码会抛出错误。我检查了函数中使用 self
定义的变量的 dir()
和 none。我不认为我犯了语法错误,其他 classes 中的代码工作正常。
这是我的代码:
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
定义的变量?
编辑:
我不久前做了这个 post,现在我知道的更多了,我只是想澄清一些事情。
第一个:
这是设计用于 python_add_in 的代码。 Python 插件根据您在设置时给它的一些参数创建一个工具栏,以及您放入模板中的任何 python 代码,它都会根据这些参数生成。这实质上意味着上面脚本中的所有 classes 都是在单击或使用工具栏中的按钮和其他工具栏对象时发生的事件。
第二个:
这个问题的解决方案实际上不在公认的答案中,我的错。
问题的根本原因是我使用了我在脚本中声明的 class 名称,例如 findingCoordinates
。 python_add_in 不会将这些 class 名称识别为它希望根据您在开始编码之前填写的模板接收的 classes 的名称。
考虑到这一点,问题是我试图调用 class 就 python_add_in 而言根本不存在的 es。解决方案是继续使用 class 名称 python_add_in 工具希望您使用。这些名称位于 class 定义下方的文档字符串中,因此在我有 findingCoordinates
的地方我应该有 Tool
.
希望对您有所帮助。
self
指的是您定义的 class 的实例,因此要访问这些值,您需要创建 class 的实例,调用方法,然后访问实例中的值。
例如:
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
编辑:您似乎也对 scoping/namespaces 感到困惑。没有全局定义 x
或 y
;它们只存在于 class 个实例中。这也将允许您为 class.
x
和 y
值
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)