有括号的方法和没有括号的方法有什么区别?

2024-06-24 12:44:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习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.')

Tags: andtheinforbypopmaxsheet
1条回答
网友
1楼 · 发布于 2024-06-24 12:44:08

要添加更多细节,您所指的是一个属性,而不是一个方法/函数。如果我们回顾一下课堂,我们可以看到不同之处。假设我有一门课叫狗:

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说出他的名字:

rusty.sayName()

rusty是一只狗,sayName()是一种方法。这是狗能做的。但是rusty也有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:

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}"

这可能会造成混淆,因为很难知道您正在访问的值是由函数/方法提供的,还是由属性提供的。也许,我没有在init中编写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()}")

注意我如何将print语句中的self.lastname更改为self.lastname()?这是因为我想要的值不再是属性,而是方法的结果。要知道这一点,唯一的办法就是理解它最初是如何编写的,或者浏览一下我那奇妙的狗库中的文档。更糟糕的是,我还可以将lastName()编写为一个创建attribute.lastName的方法,我可以在我的代码中这样得到它:

rusty = Dog("Black", "Rusty")
rusty.lastName()
print(rusty.lastname)

不过,另一个提示是,如果某个东西需要传递参数,那么它将是一个方法或函数。套管也有一些约定,但这并不是一个很好的指南。不过,希望这能解释这种差异

相关问题 更多 >