Может кто-нибудь объяснить, почему это происходит при использовании openpyxl 2.6.2? - PullRequest
0 голосов
/ 07 июня 2019

Насколько я понимаю, workbook.get_sheet_names() устарела, и мы должны использовать wb.sheetnames вместо openpyxl 2.6.2.

wb.sheetnames возвращает list всех листов, так почемумы не можем сделать это?

    import openpyxl
    wb=openpyxl.load_workbook('example.xlsx') #loading the workbook
    wb.sheetnames #getting the sheetnames with the new recomended code
    #output:['Sheet']
    wb.sheetnames[0]='Another name'
    wb.sheetnames[0] # Checking if it were changed or not
    #output:['Sheet']

Почему вышеприведенный код не работает, если wb.sheetnames действует как list?Ошибка не отображалась, но я не увидел ожидаемых изменений

Вот как выглядит example.xls:

A                         B             C
1 4/5/2015 13:34  Apples          73
2 4/5/2015 3:41   Cherries        85
3 4/6/2015 12:46  Pears           14
4 4/8/2015 8:59   Oranges         52
5 4/10/2015 2:07  Apples          152
6 4/10/2015 18:10 Bananas         23
7 4/10/2015 2:40  Strawberries    98

Ответы [ 2 ]

4 голосов
/ 07 июня 2019

Это потому, что sheetnames является свойством ; другими словами, он выглядит как атрибут экземпляра, но когда вы обращаетесь к нему, функция фактически вызывается. Вы можете увидеть этот ответ для более подробной информации.

Теперь, если мы посмотрим на источник openpyxl, мы можем найти определение sheetnames:

    @property
    def sheetnames(self):
        return [s.title for s in self._sheets]

sheetnames создает и возвращает новый list каждый раз, когда он вызывается, что вы можете доказать с помощью id:

from openpyxl import Workbook

book = Workbook()

a = book.sheetnames
b = book.sheetnames

print(id(a) == id(b))

Выход:

False

Из-за этого вы на самом деле просто изменяете первый элемент этого нового list, который создается каждый раз, когда вы вызываете sheetnames.

2 голосов
/ 07 июня 2019

Ссылка на соответствующий раздел документации

wb.sheetnames вернет список строк (т. Е. Только имена листов) , wb.sheetnames[0] - это просто строка. Когда вы делаете wb.sheetnames[0]='Another name', вы изменяете первую строку в списке, возвращаемом wb.sheetnames, но это изменение не имеет никакого практического / видимого эффекта, поскольку этот список не назначен какой-либо переменной.

также существует wb.worksheets, который будет возвращать список объектов листа . Вы можете использовать этот метод для доступа к соответствующему листу, а с помощью свойства Worksheet.title сделать wb.worksheets[0].title='New Title'

from openpyxl import Workbook
wb = Workbook()
print(wb.sheetnames)
print(type(wb.sheetnames[0]))
print(wb.worksheets) 
print(type(wb.worksheets[0]))
wb.worksheets[0].title='New Title'
print(wb.sheetnames)
print(wb.worksheets)

выход

['Sheet']
<class 'str'>
[<Worksheet "Sheet">]
<class 'openpyxl.worksheet.worksheet.Worksheet'>
['New Title']
[<Worksheet "New Title">]

Примечание - для примера я использую новый экземпляр Workbook с одним листом внутри

...