Предположим, что у меня есть GUI:
import tkinter as tk
root = tk.Tk()
btn = tk.Button(root, text="Press")
btn.pack()
root.mainloop()
См., когда btn
нажата, вызывает свою собственную функцию , которая очень похожа на button_press_handle
в следующем примере:
def button_press_handle(callback=None):
if callback:
callback() # Where exactly the method assigned to btn['command'] is being callled
с:
button_press_handle(btn['command'])
Вы может просто предположить, что параметр command
должен быть установлен как ссылка на метод, который мы хотим назвать, аналогичный callback
в button_press_handle
.
Без аргументов
Итак, если я хотел print
что-то при нажатии кнопки I необходимо установить:
btn['command'] = print # default to print is new line
Обратите внимание на недостаток в ()
с помощью метода print
, который опущен в том смысле, что: " Это имя метода, которое я хочу, чтобы вы вызывали при нажатии, но не вызываете его именно в этот момент ». Однако я не передал никаких аргументов для print
, поэтому он печатал все, что он печатает, когда без аргументов.
W ith Аргумент (ы)
Теперь Если бы я хотел также передать аргументы методу, который я хочу называть при нажатии кнопки, я мог бы использовать анонимные функции, которые могут быть созданы с помощью оператора lambda , в этом случае для встроенного метода print
, например:
btn['command'] = lambda arg1="Hello", arg2=" ", arg3="World!" : print(arg1 + arg2 + arg3)
Без Аргументы
Вы также можете добиться этого с помощью оператора lambda
, но он считается плохим и поэтому я не буду включать его здесь. Хорошей практикой является определение отдельного метода multiple_methods
, который вызывает нужные методы, а затем устанавливает его как ответ на нажатие кнопки:
def multiple_methods():
print("Vicariously") # the first inner callback
print("I") # another inner callback
С Аргумент (s)
Чтобы передать аргумент (ы) методу, который вызывает другие методы, снова используйте инструкцию lambda
, но сначала:
def multiple_methods(*args, **kwargs):
print(args[0]) # the first inner callback
print(kwargs['opt1']) # another inner callback
, а затем установите :
btn['command'] = lambda arg="live", kw="as the" : a_new_method(arg, opt1=kw)
Также обратите внимание, что callback
не может реально return
, потому что он только вызывается внутри button_press_handle
] с callback()
в отличие от return callback()
. Это делает return
, но не вне этой функции. Таким образом, вам лучше изменить объект (ы), которые доступны в текущей области.
Ниже приведен вызов метода, который меняет текст btn
при каждом нажатии кнопки:
import tkinter as tk
i = 0
def text_mod():
global i, btn # btn can be omitted but not sure if should be
txt = ("Vicariously", "I", "live", "as", "the", "whole", "world", "dies")
btn['text'] = txt[i] # the global object that is modified
i = (i + 1) % len(txt) # another global object that gets modified
root = tk.Tk()
btn = tk.Button(root, text="My Button")
btn['command'] = text_mod
btn.pack(fill='both', expand=True)
root.mainloop()
Да, просто добавьте конструктора для Грузоперевозок. Вы, вероятно, захотите добавить конструктора к Автомобилю также, хотя не обязательно общедоступный:
public class Car {
protected Car(Car orig) {
...
}
public class Truck extends Car {
public Truck(Car orig) {
super(orig);
}
...
}
, Как правило, обычно лучше сделать классы любым листом (и Вы могли бы хотеть отметить окончательных), или краткий обзор.
выглядит, как будто Вы хотите Car
объект и затем имеете тот же экземпляр, превращаются Truck
. Лучший способ сделать это состоит в том, чтобы делегировать поведение к другому объекту в Car
(Vehicle
). Так:
public final class Vehicle {
private VehicleBehaviour behaviour = VehicleBehaviour.CAR;
public void becomeTruck() {
this.behaviour = VehicleBehaviour.TRUCK;
}
...
}
, Если Вы реализуете Cloneable
тогда, можно "автоматически" скопировать объект в экземпляр того же класса. Однако существует много проблем с этим, включая необходимость скопировать каждое поле изменяемых объектов, которое подвержено ошибкам и запрещает использование финала.
Вы могли использовать API Reflection, чтобы циклично выполниться через каждое из полей Car и присвоить значение эквивалентным полям Truck. Это может быть сделано в грузовике. Далее это - единственный способ получить доступ к частным полям Автомобиля - по крайней мере, в автоматическом смысле, если это менеджер безопасности не существует и доступ ограничения к частному полю.
Да, необходимо сделать это вручную. Необходимо будет также решить, как "глубоко" скопировать вещи. Например, предположите, что Автомобиль имеет набор шин - Вы могли сделать мелкий копия набора (таким образом, что, если бы исходный объект изменяет содержание своего набора, новый объект видел бы изменение также), или Вы могли сделать глубокий копия, которая создала новый набор.
(Это - то, где неизменные типы как String
часто пригождаются - нет никакой потребности клонировать их; можно просто скопировать ссылку и знать, что содержание объекта не изменится.)
я должен был бы записать моему собственному конструктору копии? Это должно было бы быть обновлено каждый раз, Автомобиль получает новое поле...
По существу, да - Вы не можете только преобразовать объект в Java.
, К счастью, Вы не должны писать весь код сами - изучают свободное-городское-население-beanutils , конкретно методы как cloneBean. Это имеет добавленное преимущество, что Вы не должны обновлять его каждый раз, когда это получает новое поле!
Вам будет нужен конструктор копии, но Ваш конструктор копии может использовать отражение, чтобы найти общие поля между двумя объектами, получить их значения от "опытного" объекта и установить их на дочернем объекте.