[Python] Как обратиться к словарю класса во время его создания?

psihodog

Т.е. вот так:

class SomeClass(object):
for i in range(10):
# вот здесь хочется создать члены класса meth0...meth9

pilot

Как показала практика, любая созданная внутри локальная переменная станет атрибутом класса.
class SomeClass(object):
for i in range(10):
a=i
some = SomeClass
print some.i
print some.a
Я чего-то не понимаю?(например, что такое "члены класса")

zya369

class SomeClass(object):
for i in range(10):
# вот здесь хочется создать члены класса meth0...meth9

я конечно в петоне не шибко силен( ) - но "здесь" это где?
когда должен выполнятся данный код?
почему не создать методы в конструкторе?

psihodog

нет, мне нужно не это...
мне нужно:
print some.meth0
...
print some.meth9

psihodog

>когда должен выполнятся данный код?
думаю, непосредественно перед созданием класса
>почему не создать методы в конструкторе?
нет, писать для этого случая метакласс -- это из пушки по воробьям.

pilot

ЭЭЭ, это нужно до создания класса?
Эти методы ведь еще не определены могут быть?
почему не в __init__?
Дешево, сердито и некрасиво:
обертку сделать и getattr с setattr'ом перегрузить.
 class A:
def method(self):
pass
data = []
for i in range(10):
a = i
#print __dict__
print locals
print globals
print method
#print __class__
def __init__(self):
pass

a = A
print a.a
print a.i

pilot

classmethod и staticmethod
или
class B:
def __init_(self):
pass
def meth(self):
pass
class A(B):
print B.meth

zya369

# вот здесь хочется создать члены класса meth0...meth9
все равно не понял, чего хочется

>>> class SomeClass:
... def __init__(self):
... self.method0 = lambda x,y: x + y

чем это не подходит :?
ЗЫ сорри, если туплю

pilot

+1
объясните (ну хоть примерно) зачем хоть извращаться-то надо :-)

psihodog

ЭЭЭ, это нужно до создания класса?
Эти методы ведь еще не определены могут быть?
мне не нужно вызывать их, мне нужно определить члены класса.
т.е. написать что-то вроде того:

def getf(n): ...
class A(object):
meth0= getf(0)
meth1= getf(1)
...
meth9= getf(9)

psihodog

чем это не подходит :?
ну тем, что это не то что я хочу =)
это будут аттрибуты инстанса, а не класса.
для начала, они не будут баундиться. :-)
(т.е. при их вызове, объект не будет подставляться первым параметром)
ну и ещё куча других отличий

pilot

classmethod - тоже не то?

zya369

class A(object):
meth0= getf(0)
meth1= getf(1)
...
meth9= getf(9)

а потом ты хочешь дергать inst.meth0 чтобы в getf вместо x передавался self?

zya369

в общем, если да, то

def f1(x):
print x.XYZ
class C1:
def __init__(self):
self.XYZ = 'asd'
self.method0 = lambda : f1(self)
x = C1
x.method0

pilot

def f1(x):
print x.XYZ
class C1:
method0 = f1
def __init__(self):
self.XYZ = 'asd'
x = C1
x.method0

Делать то же самое правильней вот так.

pilot

А если проблема в цикле - то eval и exec

psihodog

а потом ты хочешь дергать inst.meth0 чтобы в getf вместо x передавался self?
нет, getf возвращает функции (свою для каждого n которst я хочу запихнуть в meth0..9.

psihodog

короче проблема не в том для чего мне это нужно, а в том, что мне нужен тот самый временный словарь, в котором исполняется код класса.
вот это, например:
class A(object):
...
dic= locals
...

работает. и даже в этот самый dic реально можно запихнуть что-нбудь (проверял но в документации Питона написано, что:
locals( )
Update and return a dictionary representing the current local symbol table. Warning: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter.

Т.е., не гарантируется, что изменения отразятся. Сейчас-то они отражаются, но поменяют они там что-нибудь и у меня вылезет баг.

zya369

class C1:
method0 = f1

То что написал я можно сделать внутри __init__ в цикле
(а изначально речь шла о цикле )

pilot

ну тогда да,
setattr(self, 'method%d'%i, lambda x: return i)
, например.
только непонятно, почему __init__ не нравится?

psihodog

только непонятно, почему __init__ не нравится?
ну блин, я ж написал, почему.... это будут методы инстанса. и для каждого нового инстанса они будут присваиваться...

pilot

Некрасивое решение exec'ом все равно сработает

vall

вот это работает
def g(b):
return lambda self,c: self.a+b*c
class x:
a = 1
m2 = g(2)
m3 = g(3)
a = x
print a.m2(10 a.m3(10)

ты это хочешь получить?

psihodog

ты это хочешь получить?
я не понял, что ты предложил? я хочу, чтобы мне не пришлось писать
m1= ...
m2= ...
m3= ...
...
а можно было написать
for i in range(10)
m_i= ...

vall

так бы сразу и сказал
def g(b):
return lambda self,c: self.a+b*c
class x:
a = 1
for i in range(10):
x.__dict__['m%s'%i] = g(i)
a = x
print a.m2(10a.m3(10)

psihodog

так бы сразу и сказал
я так сразу и сказал.
только то что ты мне написал мне не подходит, потому что я хочу сделать это в теле класса, т.е. ещё ДО создания класса.

pilot

Во:
a = type('A'dict(
zip(
map(lambda x:'method%d'%x,range(10
map(lambda x: lambda y:x,range(10


print a.method5

psihodog


молодец... чтоб тебе так всю жизнь классы создавать
там ведь не только эти методы есть %)
ещё раз вопрос! как получить текущий временный словарь, если это возможно, конечно.
я даже приводил плохое решение с locals. оно плохое именно потому что нет гарантий, что изменения сохранятся.
есть ли гарантированное решение?

pilot

class B(type('A'dict(
zip(
map(lambda x:'method%d'%x,range(10
map(lambda x: lambda y:x,range(10
:
def __init__(self):
pass
def method(self):
print 'hello world'

B.method

pilot

я даже приводил плохое решение с locals. оно плохое именно потому что нет гарантий, что изменения сохранятся.
есть ли гарантированное решение?
Я такого не встречал, думаю что про него (если бы оно было) должно было быть написано рядом со словами "в locals пихать низзя"

psihodog

vall

только то что ты мне написал мне не подходит, потому что я хочу сделать это в теле класса, т.е. ещё ДО создания класса.
разинь глазки - я методы добавляю в класс, а не в экземпляр класса.

pilot

разуй глазки - я методы добавляю в класс, а не в экземпляр класса.
Ты не о том.

vall

в мысле? в итоге у нас получается класс с нужнымы свойствами.
есть методы сгенерированные внешней функцией имеющие доступ к полям класса.
что ещё нужно? чтоб цикл шёл не после описания класс а внутри? это так важно?
вот как выковырять текущее пространство имён я не знаю.
да и в момент описания имя класса ещё не внесено в пространство имён.

pilot

в мысле? в итоге у нас получается класс с нужнымы свойствами.

По уму надо метакласс писать.
Навел немножко красоты:
def A(*args):
class A:
def __init__(self,string):
print string
map(lambda i: setattr(A,'method%d'%i,lambda y:irange(10
return A(*args)

a = A('hello world')
print a.method5

(запихивать можно и в __dict__ - это уж как мозги завернутся)
чтоб цикл шёл не после описания класс а внутри? это так важно?

Видимо это навязчивая идея :-)
вот как выковырять текущее пространство имён я не знаю.

locals+globals

vall

locals+globals
я же написал - в момент описания класса там ничего ещё нет.
По уму надо метакласс писать.
прикольно.

pilot

Как показала практика, любая созданная внутри локальная переменная станет атрибутом класса.
class SomeClass(object):
for i in range(10):
a=i
some = SomeClass
print some.i
print some.a

Т.е. в него запихивается в процессе.

psihodog

чтоб цикл шёл не после описания класс а внутри? это так важно?
это важно, если при создании класса, с объектами, которые перечислены в словаре что-то делается

psihodog

я же написал - в момент описания класса там ничего ещё нет.
а проверить прежде чем писать слабо?
Вот, запусти:

class A(object):
a= 1
print locals
locals['b']= 2
locals['a']= 3
print A.a, A.b

vall

Т.е. в него запихивается в процессе.
в процессе чего? в процессе описания класса - один раз.
class SomeClass(object):
for i in range(10):
a=i
print i

some = SomeClass
some2 = SomeClass
print some.i
print some.a

pilot

в процессе чего? в процессе описания класса - один раз.
Да. Вот и хорошо.

vall

ну это да, но самого класса ещё нет как класса.
Да. Вот и хорошо.
ну вот и замечательно.
Оставить комментарий
Имя или ник:
Комментарий: