我正在学习OpenPyXL,这是《自动化无聊的东西》教科书的一部分。我的问题与以下代码行有关:
for row in range (2, sheet.max_row + 1): # Starts at the row 2 and steps by 1 until highest row
为什么我在运行Type Error: 'int' object is not callable
方法时得到sheet.max_row()
,而在删除括号时却没有得到?具有括号的方法之间的区别是什么-例如,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.')
答案 0 :(得分:0)
要添加更多详细信息,您所指的是属性,而不是方法/函数。如果我们回顾一下类,我们可以看到区别。假设我有一门叫狗的课程:
class Dog():
def __init__(self, color, name):
self.color = color
self.name = name
def sayName(self):
print(f"My name is {self.name}")
我们有什么?我的课有两种方法, init ()和sayName()。这些做某事。我可以使用init创建一个新实例,如下所示:
rusty = Dog("black", "Rusty")
我可以通过以下方式来生锈地说他的名字:
rusty.sayName()
rusty是一条狗,sayName()是一种方法。狗可以做的事。但是生锈也有self.name和self.color,这些不是方法,而是属性。当我们运行 init ()时,我们确定了这些属性是什么,但是我们可能拥有的属性并非直接来自传递给init的。我可以添加:
class Dog():
def __init__(self, color, name):
self.color = color
self.name = name
self.lastname = f"Mc{name[:-1]}erson"
def sayName(self):
print(f"My name is {self.name} {self.lastname}")
现在我有3个属性,其中一个我没有直接传递给init方法。如果我现在生锈了:
rusty = Dog("Black", "Rusty")
然后我可以调用sayName(),它将显示:
My name is Rusty McRusterson
但是,我也可以这样做:
print(rusty.lastname)
这将访问该属性并进行打印:
McRusterson
但是,大多数方法不会打印到控制台,它们会返回一个值。像这样:
def sayName(self):
return f"My name is {self.name} {self.lastname}"
这是令人困惑的地方,因为很难知道您正在访问的值是由函数/方法还是由属性提供的。也许不是在初始化中编写self.lastname定义,而是添加了另一种方法:
class Dog():
def __init__(self, color, name):
self.color = color
self.name = name
def lastName(self):
name_slice = self.name[:-1]
lastname = f"Mc{name_slice}erson"
return lastname
def sayName(self):
print(f"My name is {self.name} {self.lastName()}")
注意我如何将打印语句中的self.lastname更改为self.lastName()?这是因为我想要的值不再是属性,而是方法的结果。唯一了解这种情况的方法是首先了解它是如何编写的,或者在我很棒的狗库中搜寻文档。更糟的是,我还可以将lastName()编写为创建属性.lastname的方法,我将在代码中输入以下内容:
rusty = Dog("Black", "Rusty")
rusty.lastName()
print(rusty.lastname)
不过,另一个提示是,如果某些东西需要传递参数,它将成为方法或函数。也有大小写约定,但这并不是指导性内容。希望这可以解释差异!