Python: как обратиться к классу из него (как рекурсивная функция)

Для рекурсивной функции мы можем сделать:

def f(i):
  if i<0: return
  print i
  f(i-1)

f(10)

Однако существует ли способ сделать следующую вещь?

class A:
  # do something
  some_func(A)
  # ...
25
задан KL. 9 January 2010 в 23:44
поделиться

9 ответов

Вы не можете использовать конкретный синтаксис, который вы описываете из-за времени, в которое они оцениваются. Причина, по которой приведенный пример функции работает, заключается в том, что вызов f (i-1) в теле функции вызван тем, что разрешение имени f не выполняется до тех пор, пока функция не будет фактически вызвана. . На данный момент f существует в рамках выполнения, поскольку функция уже была оценена. В случае примера класса ссылка на имя класса ищется, пока определение класса все еще оценивается. Таким образом, он еще не существует в локальной области.

В качестве альтернативы, желаемое поведение может быть достигнуто с помощью метакласса, подобного такому:

class MetaA(type):

    def __init__(cls):
        some_func(cls)

class A(object):
    __metaclass__=MetaA
  # do something
  # ...

Используя этот подход, вы можете выполнять произвольные операции с объектом класса во время оценки класса.

8
ответ дан 28 November 2019 в 21:30
поделиться

Нет. Работает в функции, так как содержимое функции выполняется во время вызова. Однако содержимое класса выполняется в определенное время, и в этот момент класс еще не существует.

Обычно это не проблема, потому что после определения класса можно взломать другие члены класса, так что можно разбить определение класса на несколько частей:

class A(object):
    spam= 1

some_func(A)

A.eggs= 2

def _A_scramble(self):
    self.spam=self.eggs= 0
A.scramble= _A_scramble

Однако, довольно необычно хотеть вызвать функцию на классе в середине его собственного определения. Не ясно, что вы пытаетесь сделать, но есть шанс, что вы будете лучше с декораторами (или с относительно новыми декораторами класса ).

1
ответ дан 28 November 2019 в 21:30
поделиться

Нет способа сделать это в рамках класса, только если сначала A не было определено как что-то другое (и тогда некоторая_func(A) сделает что-то совершенно отличное от того, что вы ожидаете)

Если только вы не делаете какую-то проверку стека для добавления битов в класс, кажется странным, почему вы хотите сделать это. Почему бы просто не:

class A:
    # do something
    pass

some_func(A)

То есть, запустить некоторую_функцию на A после того, как она будет сделана. В качестве альтернативы можно использовать декоратор класса (синтаксис для него был добавлен в 2.6) или метаклас, если вы захотите как-то изменить класс A. Не могли бы вы прояснить случай использования?

1
ответ дан 28 November 2019 в 21:30
поделиться

Чего ты хочешь достичь? Можно получить доступ к классу, чтобы скорректировать его определение с помощью метакласса, но это не рекомендуется.

Ваш пример кода может быть написан просто как:

class A(object):
    pass
some_func(A)
0
ответ дан 28 November 2019 в 21:30
поделиться

Можно ссылаться на имя класса внутри его тела (как внутри определений методов), если оно на самом деле находится в области видимости..... Каким оно будет, если будет определено на верхнем уровне. (В других случаях, вероятно, нет, из-за причуд Python scoping quirks!).

Для иллюстрации scoping gotcha попробуйте инстанцировать Foo:

class Foo(object):
    class Bar(object):
        def __init__(self):
            self.baz = Bar.baz
        baz = 15
    def __init__(self):
        self.bar = Foo.Bar()

(Он будет жаловаться на то, что глобальное имя 'Bar' не определено.)


Кроме того, что-то подсказывает мне, что вы можете захотеть заглянуть в методы класса: docs о функции метода класса (для использования в качестве декоратора), соответствующий вопрос SO. Редактирование: Хорошо, это предложение может быть вообще неуместным.... Просто первое, о чем я подумал, когда читал ваш вопрос, было что-то вроде альтернативных конструкторов и т.д. Если вам подходит что-то более простое, держитесь подальше от странностей @classmethod. :-)

.
0
ответ дан 28 November 2019 в 21:30
поделиться

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

http://www.red-gate.com/Products/schema_compare_for_oracle/index.htm

-121--683631-

В emacs я не думаю, что это встроено, я могу ошибаться, но если не здесь функция для этого:

(defun open-in-browser()
  (interactive)
  (let ((filename (buffer-file-name)))
    (browse-url (concat "file://" filename))))
-121--1456881-

В Python вы не можете ссылаться на класс в теле класса, хотя в языках, таких как rub

Вместо этого в Python можно использовать декоратор класса, но он будет вызван после инициализации класса. Другим способом может быть использование метакласса, но это зависит от того, чего вы пытаетесь достичь.

19
ответ дан 28 November 2019 в 21:30
поделиться

Если вы хотите обратиться к одному и тому же объекту, просто используйте «self»: ​​

class A:
    def some_func(self):
        another_func(self)

Если вы хотите создать новый объект того же класса, просто сделайте это:

class A:
    def some_func(self):
        foo = A()

, если Вы хотите получить доступ к метакласу Metaclass объекта класса (скорее всего, не то, что вы хотите), опять же, просто сделайте это:

class A:
    def some_func(self):
        another_func(A) # note that it reads A, not A()
2
ответ дан 28 November 2019 в 21:30
поделиться

Большинство кода в классе будет внутри определений методов, в этом случае можно просто использовать имя A.

-1
ответ дан 28 November 2019 в 21:30
поделиться

Сходства

  1. Кобол и Java собирались изменить мир и решить проблему программирования.

  2. Ни один из них не оправдал первоначального ажиотажа.

  3. Сейчас существуют очень большие, раздутые программы Cobol и Java, которые используются банками и являются «наследием»... слишком большой и критический, чтобы переписать или выбросить.

  4. Кобол представляет идею наличия длинных, читаемых имен в их коде. Java рекомендует длинные, читаемые имена.

Отличия

  1. Кобола придумал американец, Изящество Мюррей Хоппер, получивший высшую награду Министерства обороны, медаль «За выдающиеся заслуги в обороне».

  2. Яву изобрел канадец Джеймс Гослинг, получивший высшую гражданскую честь Канады, офицер Ордена Канады.

3 COBOL convention использует «-» для разделения слов в названиях, Java convention использует верхний/нижний CamelCase.

-121--4904252-

Если вы хотите сделать только небольшую халтурную вещь сделать

class A(object):
    ...
some_func(A)

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

class AType(type):
    def __new__(meta, name, bases, dct):
        cls = super(AType, meta).__new__(meta, name, bases, dct)
        some_func(cls)
        return cls

class A(object):
    __metaclass__ = AType
    ...

тип является метаклассом по умолчанию. Экземпляры метаклассов являются классами, поэтому __ new __ возвращает измененный экземпляр (в данном случае) A .

Для получения дополнительной информации о метаклассах см. http://docs.python.org/reference/datamodel.html#customizing-class-creation .

1
ответ дан 28 November 2019 в 21:30
поделиться
Другие вопросы по тегам:

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