*
и **
имеют специальное использование в списке аргументов функции. *
подразумевает, что аргумент представляет собой список, а **
подразумевает, что аргумент является словарем. Это позволяет функциям принимать произвольное количество аргументов
В Python вы не можете ссылаться на класс в классе, хотя на таких языках, как Ruby, вы можете это сделать.
В Python вместо этого вы можете использовать декоратор класса, но он будет вызываться, как только класс будет инициализируется. Другим способом может быть использование метакласса, но это зависит от того, чего вы пытаетесь достичь.
неа. Он работает в функции, потому что содержимое функции выполняется во время вызова. Но содержимое класса выполняется в time-time, и в этот момент класс еще не существует.
Обычно это не проблема, потому что вы можете взломать новых членов в класс после определения его, так что вы можете разделите определение класса на несколько частей:
class A(object):
spam= 1
some_func(A)
A.eggs= 2
def _A_scramble(self):
self.spam=self.eggs= 0
A.scramble= _A_scramble
Однако довольно необычно хотеть вызывать функцию в классе в середине своего собственного определения. Непонятно, что вы пытаетесь сделать, но, скорее всего, вам будет лучше decorators (или относительно новые декодеры класса ).
Если вы хотите обратиться к одному и тому же объекту, просто используйте «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()
types.ClassType
(или type
при использовании классов нового стиля или python3)
– Crast
10 January 2010 в 00:55
Если целью является вызов функции some_func
с классом в качестве аргумента, один ответ заключается в объявлении some_func
в качестве декоратора класса. Обратите внимание, что декоратор класса вызывается после инициализации класса. Он будет передан классу, который оформляется в качестве аргумента.
def some_func(cls):
# Do something
print(f"The answer is {cls.x}")
return cls # Don't forget to return the class
@some_func
class A:
x = 1
Если вы хотите передать дополнительные аргументы в some_func
, вы должны вернуть функцию из декоратора:
def some_other_func(prefix, suffix):
def inner(cls):
print(f"{prefix} {cls.__name__} {suffix}")
return cls
return inner
@some_other_func("Hello", " and goodbye!")
class B:
x = 2
Декораторы классов могут быть скомпонованы, что приводит к их вызыванию в обратном порядке, которые они объявляются:
@some_func
@some_other_func("Hello", "and goodbye!")
class C:
x = 42
. Результатом является:
# Hello C and goodbye!
# The answer is 42
Это нормально, чтобы ссылаться на имя класса внутри его тела (например, внутри определения метода), если оно действительно находится в области видимости ... Что будет, если оно определено на верхнем уровне. (В других случаях, вероятно, нет, из-за особенностей Python для определения области видимости!).
Для иллюстрации получения лупы, попробуйте создать экземпляр 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 для функции classmethod (to использовать в качестве декоратора), соответствующий вопрос SO . Edit: Хорошо, поэтому это предложение может быть не совсем уместным ... Просто первое, что я подумал, когда читал ваш вопрос, было таким, как альтернативные конструкторы и т. д. Если что-то более простое соответствует вашим потребностям, избегать @classmethod
странности. : -)
В пределах класса не существует способа сделать это, если только A не было определено как-то другим (а затем some_func (A) будет делать что-то совершенно отличное от того, что вы ожидаете)
Если вы не проводите проверку стека для добавления бит в класс, кажется странным, почему вы хотите это сделать. Почему не просто:
class A:
# do something
pass
some_func(A)
То есть, запустите some_func на A после его создания. В качестве альтернативы вы можете использовать декоратор класса (синтаксис для него был добавлен в версии 2.6) или метакласса, если вы хотите каким-то образом изменить класс A. Не могли бы вы пояснить свой прецедент?
Если вы хотите сделать небольшую взломанную вещь, сделайте
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
...
type
является метаклассом по умолчанию. Экземпляры метаклассов являются классами, поэтому __new__
возвращает модифицированный экземпляр (в данном случае) A
.
Подробнее о метаклассах см. В http://docs.python.org/reference /datamodel.html#customizing-class-creation.
Вы не можете с конкретным синтаксисом, который вы описываете, из-за времени, когда они оцениваются. Причина, по которой приведенная в примере функция работает, заключается в том, что вызов функции f (i-1) внутри тела функции заключается в том, что разрешение имени f не выполняется до тех пор, пока функция не будет фактически называется. В этот момент f существует в рамках выполнения, так как функция уже была оценена. В случае примера класса ссылка на имя класса просматривается во время определения определения класса. Таким образом, он еще не существует в локальном масштабе.
В качестве альтернативы желаемое поведение может быть выполнено с использованием метакласса, подобного такому:
class MetaA(type):
def __init__(cls):
some_func(cls)
class A(object):
__metaclass__=MetaA
# do something
# ...
Используя этот подход, вы можете выполнять произвольные операции над объектом класса в то время, когда класс оценены.
Большинство кода в классе будут внутри определения методов, и в этом случае вы можете просто использовать имя A
.
Чего вы хотите достичь? Можно получить доступ к классу, чтобы настроить его определение с помощью метакласса, но это не рекомендуется.
Ваш образец кода может быть написан просто как:
class A(object):
pass
some_func(A)