Почему динамическим языкам нравится Ruby, и Python не имеют понятие интерфейсов как в Java или C#?

Я немного очистил код, присвоив индексам правильные имена.

С точки зрения решения вашей проблемы, я добавил два разных индекса строки, один для X, другой для пустого. В зависимости от того, является ли он X или пустым, вы увеличиваете либо одно, либо другое.

Option Explicit

Sub Main()


Dim Wb As Workbook 'Workbook I'm printing each managers employee roster to and saving off a copy to a folder
Dim Data, Last, Login, chkVal 'Data = data I'm printing into template / Last = Manager name / Login = Manager Login ID
Dim row_data As Long, col_wb As Long, col_data As Long, row_wb As Long
Dim Dest1 As Range, Dest2 As Range, FinalDest As Range 'Dest1 = Sheets(1) of Wb / Dest2 = Sheets(2) of Wb
Dim row_index_x As Long, row_index_blank As Long, isX As Long

Set Wb = Workbooks("Template.xlsx") 'Sets template for each file cut

Set Dest1 = Wb.Sheets("Currently Eligible").Range("B2")
Set Dest2 = Wb.Sheets("Newly Eligible").Range("B2")

With ThisWorkbook.Sheets("Sheet1")
    Data = .Range("AA2", .Range("A" & Rows.Count).End(xlUp)) 'Raw data
End With

Wb.Activate
Application.ScreenUpdating = False

' initialise row indices to 0, ignore header as Dest1 and Dest2 already at B2.
row_index_x = 0
row_index_blank = 0

For row_data = 1 To UBound(Data) 'Row 1 to Ubound of Data(rows)

    ' if manager name changed between this row and previous row
    If Data(row_data, 1) <> Last Then 'only print array to Wb one manager at a time, we see when managers change because values in Data(row_data,1) will <> the next cell

        If row_data > 1 Then 'skip header

            ' save wb every time manager changes
            Wb.SaveCopyAs ThisWorkbook.Path & Application.PathSeparator & _
              ValidFileName(Login & " - " & Last & " - Shift Differential Validation.xlsx")

        End If

        With Sheets("Exempt Population")
            .Rows(2 & ":" & .Rows.Count).ClearContents 'Clears previous managers data
        End With

        Last = Data(row_data, 1) 'Manager last name is in Column A
        chkVal = Data(row_data, 8) 'Check for X or Blank in Column H
        Login = Data(row_data, 27) 'Manager login ID is in column AA

        ' reset output row every time manager name changes
        row_wb = 0 'Wb Row = 0

    End If

    ' for every data row, reset output column to zero (start a new row)
    col_wb = 0 'Wb Col = 0

    SaveTyping = Data(row_data, 8) 'Column my X's and Blanks are

    ' decide output destination
    If InStr(SaveTyping, "X") Then
         Set FinalDest = Dest1
         row_wb = row_index_x
         isX = 1 ' remember whether its X or blank
    End If

    If SaveTyping = "" Then
         Set FinalDest = Dest2
         row_wb = row_index_blank
         isX = 0
    End If


    ' Loop through all columns for one row of data
    ' keep output row the same, increase the output column
    For col_data = 1 To UBound(Data, 2) 'Column 1 to Ubound of Data(columns)
        FinalDest.Offset(row_wb, col_wb) = Data(row_data, col_data)
        col_wb = col_wb + 1 'next Wb column
    Next

    'row_wb = row_wb + 1 'next Wb row

    ' decide which row index to increase
    If isX = 1 Then
        row_index_x = row_index_x + 1
    Else
        row_index_blank = row_index_blank + 1
    End If

Next

SaveCopy Wb, Login, Last '<< save the last report

End Sub

14
задан Dana 3 April 2009 в 20:37
поделиться

5 ответов

Благодаря позднему связыванию им не нужен он. В Java/C# интерфейсы используются, чтобы объявить, что некоторый класс имеет определенные методы, и он проверяется в течение времени компиляции; в Python, существует ли метод, проверяется во время времени выполнения.

Перегрузка метода в Python действительно работает:

>>> class A:
...  def foo(self):
...    return "A"
...
>>> class B(A):
...  def foo(self):
...    return "B"
...
>>> B().foo()
'B'

Действительно ли они объектно-ориентированы? Я сказал бы да. Это - больше вещи подхода, а не если какой-либо конкретный язык имеет функцию X или функцию Y.

17
ответ дан 1 December 2019 в 06:35
поделиться

Динамические языки используют утиный ввод. Любой код может назвать методы на любом объекте, которые поддерживают те методы, таким образом, понятие интерфейсов является посторонним. Python действительно на самом деле поддерживает перегрузку оператора, как делает Ruby.

Так или иначе Вы, кажется, фокусируетесь на аспектах, которые не важны для объектно-ориентированного программирования. Основной фокус находится на понятиях как инкапсуляция, наследование и полиморфизм, которые составляют 100%, поддерживаемых в Python и Ruby.

18
ответ дан 1 December 2019 в 06:35
поделиться

Я могу только говорить за Python, но были предложения по интерфейсам, а также записали из дома интерфейсные примеры в прошлом.

Однако способ, которым Python работает с объектами динамично, имеет тенденцию уменьшать потребность в (и преимущество) интерфейсы в некоторой степени.

С динамическим языком Ваша привязка типа происходит во времени выполнения - интерфейсы главным образом используются для ограничений времени компиляции на объекты - если это происходит во времени выполнения, это избавляет от части необходимости в интерфейсах.

7
ответ дан 1 December 2019 в 06:35
поделиться

основанный на имени полиморфизм

"Для тех из Вас незнакомый с Python, вот быстрое введение к основанному на имени полиморфизму. Объекты Python имеют внутренний словарь, который содержит строку для каждого атрибута и метода. При доступе к атрибуту или методу в коде Python Python просто ищет строку в dict. Поэтому, если то, что Вы хотите, является классом, который работает как файл, Вы не должны наследоваться из файла, Вы просто создаете класс, который имеет методы файла, которые необходимы.

Python также определяет набор специальных методов, которые называет соответствующий синтаксис. Например, a+b эквивалентен a.add (b). Существует несколько мест во внутренностях Python, где это непосредственно управляет встроенными объектами, но основанные на имени работы полиморфизма, поскольку Вы ожидаете приблизительно 98% времени".

2
ответ дан 1 December 2019 в 06:35
поделиться

Python действительно обеспечивает перегрузку оператора, например, можно определить метод __add__ если Вы хотите перегрузиться +.

Вы обычно не должны обеспечивать перегрузку метода, так как можно передать произвольные параметры в отдельный метод. Во многих случаях тот отдельный метод может иметь уединенное тело, которое работает на все виды объектов таким же образом. Если Вы хотите иметь другой код для различных типов параметра, можно осмотреть тип или двойную отправку.

Интерфейсы являются главным образом ненужными из-за утиного ввода, как указывает rossfabricant. Несколько остающихся случаев охвачены в Python ABC интерфейсы Zope или (абстрактные базовые классы).

1
ответ дан 1 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: