Я не уверен, почему вам нужно / нужно, чтобы эти две функции были внутри вашего класса. Но есть два способа сделать это: один безопаснее, а другой легче читать, но в некоторых случаях он может быть опасен.
class A:
@staticmethod
def f():
return 2
s = f.__func__()
print("Class s = ", id(A.s))
print("Instance s = ", id(A().s))
Обе распечатки выводят то же id
, что и s
, является статическим полем из класса A
. Вам нужно вызвать __func__
для f
, потому что f
- это не функция, это статический метод , добавление этого print(type(f))
в тело класса приведет к выводу
. Если вы посмотрите, как выглядят объекты экземпляров / статических методов / классов, вы увидите, что (помимо прочего) они содержат функциональный объект, к которому вы можете получить доступ через __func__
.
Это описано в модели данных , где выполняется поиск «Методы экземпляра», «Статический метод» или «Метод класса». В частности:
Объекты статического метода предоставляют способ предотвратить преобразование объектов функции в объекты метода, описанные выше.
blockquote>Где «объекты метода» определены так:
Объект метода экземпляра объединяет класс, экземпляр класса и любой вызываемый объект (обычно пользовательскую функцию) .
Специальные атрибуты только для чтения:
blockquote>__self__
это объект экземпляра класса,__func__
это объект функции…Короткий путь
С другой стороны, вы может просто сделать следующее:
class A: def f(x): return x s = f(2)
Что может быть даже «лучше» в вашем случае, но учтите, что если вы это сделаете, то вы «не сможете» вызывать
f
в случаях изA
, потому чтоf
будетfunction
(не объект метода экземпляра). Другими словами, вы могли бы сделать следующее:print(A.f(2)) print(A().__class__.f(2))
Но прямой вызов
A().f
не будет работать должным образом (и даже может быть опасным):>>> print(A().f(2)) # Not too bad TypeError: f() takes 1 positional argument but 2 were given >>> print(A().f()) # Quite bad <__main__.A object at 0x7fab441131d0>
Последний вызов эквивалентен вызову
f
с параметромx
, установленным в экземплярA
, т.е.print(A.f(A()))
эквивалентно этому последнему вызову.В общем, я бы порекомендовал первое решение, но в вашем случае простой версии может быть достаточно, просто обязательно назовите свой «метод» (функцию)
__
, чтобы предупредить людей извне, что они не должны не используйте его, если они не знают, что делают.Каков наилучший способ?
В конце концов, вам понадобится довольно веская причина, чтобы выбрать любое из этих двух решений, поскольку у вас уже есть, вероятно, лучшее (наличие функции вне вашей учебный класс). [Тысяча сто сорок два]
Краткий ответ: установите значение атрибута exportselection
всех виджетов списка в значение False или ноль .
Из обзора pythonware виджета списка:
По умолчанию выбор экспортируется. к механизму выбора X. если ты иметь более одного списка на экран, это действительно все портит для бедного пользователя. Если он выбирает что-то в одном списке, а затем выбирает что-то в другом, исходный выбор очищается. это обычно хорошая идея отключить это механизм в таких случаях. в В следующем примере три списка используется в том же диалоговом окне:
b1 = Listbox (exportselection = 0) за предмет в семьях: b1.insert (КОНЕЦ, пункт) b2 = список (выбор экспорта = 0) для элемента в шрифтах: b2.insert (КОНЕЦ, пункт) b3 = список (выбор экспорта = 0) для элемента в стилях: b3.insert (КОНЕЦ, пункт)
Полная документация для виджетов tk основана на языке Tcl, а не на python, но ее легко перевести на python. Атрибут exportselection
можно найти на странице справочника стандартных опций .
exportselection = 0
при определении списка эта проблема решается.