我正在学习OpenPyXL,作为《自动化无聊的东西》教科书的一部分。我的问题与以下代码行有关:
for row in range (2, sheet.max_row + 1): # Starts at the row 2 and steps by 1 until highest row
为什么在运行sheet.max_row()
方法时会得到Type Error: 'int' object is not callable
,而在删除括号时却没有?有括号的方法之间有什么区别?例如,sheet.max_row()
和sheet.max_row
之间的区别。我注意到sheet.get_highest_row()
方法被sheet.max_row()
替换
我已经为以下问题生成了代码:
#!/usr/bin/env python3
"""
readCensusExcel.py
Chapter 12 - Project: Reading Date From a Spreadsheet
This program retrieves data counts the total population and the number of census tracts for each county.
"""
import os, openpyxl, pprint
os.chdir('D:\\Python\\Projects - Automate the Boring Stuff with Python\\Chapter 12\\readCensusExcel')
print('Opening workbook...')
wb = openpyxl.load_workbook('censuspopdata.xlsx')
sheet = wb['Population by Census Tract']
countyData = {} # creates a dictionary called countyData
#Fill in countyData with each county's population and tracts
print('Reading rows...')
for row in range (2, sheet.max_row + 1): # Starts at the row 2 and steps by 1 until highest row
# Each row in the spreadsheet has data for one census tract
state = sheet['B' + str(row)].value
county = sheet['C' + str(row)].value
pop = sheet['D' + str(row)].value
# countyData dictionary keys format: countyData[state abbrev][county]['pops'] or countyData[state abbrev][county]['tracts']
# Make sure the key for this state exists, it will do nothing if the key already exists
countyData.setdefault(state, {})
# Make sure the key for this county in this state exists
countyData[state].setdefault(county, {'tracts': 0, 'pop': 0})
# Each row represents one census tract, so increment by one
countyData[state][county]['tracts'] += 1
# Increase the county pop by the pop in this census tract
countyData[state][county]['pop'] += int(pop)
# Open a new text fill and write the contents of countyData to it
print('Writing results...')
resultFile = open('census2010.py', 'w')
resultFile.write('allData = ' + pprint.pformat(countyData))
resultFile.close()
print('Done.')
要添加更多细节,您所指的是一个属性,而不是一个方法/函数。如果我们回顾一下课堂,我们可以看到不同之处。假设我有一门课叫狗:
我们有什么?我的类有两个方法,init()和sayName()。这些能起作用。我可以使用init创建一个新实例,如下所示:
我可以让rusty说出他的名字:
rusty是一只狗,sayName()是一种方法。这是狗能做的。但是rusty也有self.name和self.color,它们不是方法,而是属性。当我们运行init()时,我们确定了这些属性是什么,但是我们可能有一些属性不是直接来自于被传递到init的。我可以补充:
现在我有3个属性,其中一个我没有直接传递给init方法。如果我现在创建rusty:
然后我可以调用sayName(),它将打印:
但是,我也可以这样做:
这将访问属性并打印它:
但是,大多数方法不会打印到控制台,而是返回一个值。像这样:
这可能会造成混淆,因为很难知道您正在访问的值是由函数/方法提供的,还是由属性提供的。也许,我没有在init中编写self.lastname定义,而是添加了另一个方法:
注意我如何将print语句中的self.lastname更改为self.lastname()?这是因为我想要的值不再是属性,而是方法的结果。要知道这一点,唯一的办法就是理解它最初是如何编写的,或者浏览一下我那奇妙的狗库中的文档。更糟糕的是,我还可以将lastName()编写为一个创建attribute.lastName的方法,我可以在我的代码中这样得到它:
不过,另一个提示是,如果某个东西需要传递参数,那么它将是一个方法或函数。套管也有一些约定,但这并不是一个很好的指南。不过,希望这能解释这种差异
相关问题 更多 >
编程相关推荐