[英]What is the difference between methods that have parentheses and methods that do not have parentheses?
我正在學習 OpenPyXL 作為 Automate the Boring Stuff 教科書的一部分。 我的問題與以下代碼行有關:
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.')
要添加更多詳細信息,您所指的是屬性,而不是方法/函數。 如果我們回顧類,我們可以看到差異。 假設我有一個名為 dog 的 class:
class Dog():
def __init__(self, color, name):
self.color = color
self.name = name
def sayName(self):
print(f"My name is {self.name}")
我們有什么? 我的 class 有兩個方法, 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 = 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()}")
請注意我必須如何將打印語句中的 self.lastname 更改為 self.lastName()? 那是因為我想要的值不再是一個屬性,而是一個方法的結果。 知道這一點的唯一方法是首先了解它是如何編寫的,或者在我美妙的狗庫上搜索文檔。 更糟糕的是,我還可以將 lastName() 編寫為創建 attribute.lastname 的方法,我會在我的代碼中得到它,如下所示:
rusty = Dog("Black", "Rusty")
rusty.lastName()
print(rusty.lastname)
不過,另一個提示是,如果需要將 arguments 傳遞給它,它將是一個方法或 function。 也有大小寫的約定,但這並不是一個指導。 不過,希望這能解釋差異!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.