Найти - Пользователи
Полная версия: Динамичный список аргументов
Начало » Python для новичков » Динамичный список аргументов
1
ElberMendax
Доброго времени суток. Интересует следующий вопрос:
Я передаю в *args некоторый набор элементов,что-то вроде
def f(*args):
    tmp = 0
    for p in args:
        tmp += p.f1()
f(a,b,c)
a,b,c здесь - это объекты некоторого класса, у которых есть функция f1.
получаю ошибку вида ‘tuple’ object has no attribute ‘f1’
если заменяю на
for i in range(len(args)):
    tmp += args[i].f1()
то получаю все то же самое.
Помогите пожалуйста, как можно разрешить этот вопрос.
terabayt
покажите чему равны a, b, c
у вас где-то там ошибка!
>>> def f(*args):
...     tmp = ''
...     for p in args:
...         tmp += p.__str__()
...     return tmp
... 
>>> a = 12
>>> b = 0.36
>>> c = "hello"
>>> 
>>> print f(a,b,c)
120.36hello
ElberMendax
a, b, c - объекты
у них есть поля
M #масса
coord #список с координатами
V #список скоростей 
и есть большой набор методов
одним из них является
def f1(self, obj):
    tmp = #вычисления с ними все ок
    return tmp

и получается в f передается (self, *args)
а потом идет
def f(self, *args):
    tmp = 0
    for p in args:
        tmp += p.f1(self)
    return tmp
f тоже определен в этом же классе
terabayt
в теории все хорошо, но на практике у вас ошибка
или давайте весь код или ничем не смогу помочь!
ElberMendax
Окей
Основная ф-я такая:
def RKStep(self, *args):
        k1 = self.V[0]
        l1 = self.Vx(args)
        .....
она соответственно вызывает
def Vx(self, *args):
        tmp = 0
        for planet in args:
            tmp += planet.helpVx(self)
        return -(spaceObj.G*spaceObj.Msun*self.coord[0])/((self.coord[0]**2+self.coord[1]**2)**(3/2))+tmp
которая в свою очередь вызывает
def helpVx(self, obj):
        return -(spaceObj.G*self.M*(obj.coord[0]-self.coord[0]))/(((obj.coord[0]-self.coord[0])**2+(obj.coord[1]-self.coord[1])**2)**(3/2))-(G*self.M*self.coord[0])/((self.coord[0]**2+self.coord[1]**2)**(3/2))
вызов RKStep происходит так
merc_tmp = Mercury.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Uran, Neptun)
terabayt
ну вот так и бы и сразу
вот пример который объясняет ошибку
>>> def f(*args):
...     tmp = ''
...     print args
... 
>>> def z(*args):
...     f(args)
... 
>>> a = 12
>>> b = 0.36
>>> c = "hello"
>>> 
>>> z(a,b,c)
((12, 0.36, 'hello'),)
>>> 
а вот как должен быть ваш код
def f(*args):
    tmp = 0
    for p in args[0]:
        tmp += p.f1()
f(a,b,c)
или так
def f(args):
    tmp = 0
    for p in args:
        tmp += p.f1()
f(a,b,c)
ваш пример не соответствовал действительности
в дальнейшем, если не знаете что и как работает, лучше сразу выкладывайте весь код!

все не должно быть так! но для курсача сойдет ;)
py.user.next
ElberMendax
Я передаю в *args некоторый набор элементов,что-то вроде
*args ставится тогда, когда передаёшь любое количество позиционных аргументов.

>>> def f(*args):
...     print(args)
... 
>>> f(1, 2, 3)
(1, 2, 3)
>>> f(1, 2)
(1, 2)
>>> f(1)
(1,)
>>> f()
()
>>>

Если передаёшь один аргумент, то он и будет одним аргументом:
>>> t = (1, 2, 3, 4)
>>> f(t)
((1, 2, 3, 4),)
>>>

Чтобы передать один аргумент как несколько, нужно их распаковать:
>>> t = (1, 2, 3, 4)
>>> f(*t)
(1, 2, 3, 4)
>>>
ElberMendax
Спасибо)
С этим *args теперь понятно как работать. Но возникла проблема другого рода:
 AttributeError: 'NoneType' object has no attribute 'name'
И зацикливание работы…
Я почитал и так понял что эта ошибка вылетает когда ты думаешь что работаешь в функции с экземплярами определенного класса, а на самом деле где-то зафейлился с передачей аргументов или что-то типа того:
Есть 2 кода:
class spaceObj:
    Msun = 1.998892*(10**30)
    G = 6.67191*(10**(-11))
    ae = 147098290000
    h = 86400
    
    def __init__(self, M, coord, V, N):
        self.N = N
        self.M = M
        self.coord = coord
        self.V = V
        self.data = [0] * N
        for i in range(N):
            self.data[i] = [0] * 4
    
    def helpVx(self, obj):
        return -(spaceObj.G*self.M*(obj.coord[0]-self.coord[0]))/(((obj.coord[0]-self.coord[0])**2+(obj.coord[1]-self.coord[1])**2)**(3/2))-(spaceObj.G*self.M*self.coord[0])/((self.coord[0]**2+self.coord[1]**2)**(3/2))
        
    def helpVy(self, obj):
        return -(spaceObj.G*self.M*(obj.coord[1]-self.coord[1]))/(((obj.coord[0]-self.coord[0])**2+(obj.coord[1]-self.coord[1])**2)**(3/2))-(spaceObj.G*self.M*self.coord[1])/((self.coord[0]**2+self.coord[1]**2)**(3/2))
        
    def Vx(self, *args):
        tmp = 0
        for planet in args[0]:
            tmp += planet.helpVx(self)
        return -(spaceObj.G*spaceObj.Msun*self.coord[0])/((self.coord[0]**2+self.coord[1]**2)**(3/2))+tmp
        
    def Vy(self, *args):
        tmp = 0
        for planet in args[0]:
            tmp += planet.helpVy(self)
        return -(spaceObj.G*spaceObj.Msun*self.coord[1])/((self.coord[0]**2+self.coord[1]**2)**(3/2))+tmp
        
    def copy(self, newx, newy):
        tmp = spaceObj(self.M,[newx,newy],self.V,self.N)
        return tmp
        
    def RKStep(self, *args):
        k1 = self.V[0]
        l1 = self.Vx(args)
        k2 = self.V[0] + (spaceObj.h * l1)/2
        tmp = self.copy(self.coord[0] + (spaceObj.h * k2)/2, self.coord[1] + spaceObj.h / 2)
        l2 = tmp.Vx(args)
        k3 = self.V[0] + (spaceObj.h * l2)/2
        tmp = self.copy(self.coord[0] + (spaceObj.h * k3)/2, self.coord[1] + spaceObj.h / 2)
        l3 = tmp.Vx(args)
        k4 = self.V[0] + (spaceObj.h * l3)
        tmp = self.copy(self.coord[0] + (spaceObj.h * k4), self.coord[1] + spaceObj.h)
        l4 = tmp.Vx(args)
        s1 = self.V[1]
        t1 = self.Vy(args)
        s2 = self.V[1] + (spaceObj.h * t1)/2
        tmp = self.copy(self.coord[0] + spaceObj.h / 2, self.coord[1] + (spaceObj.h * s2)/ 2)
        t2 = tmp.Vy(args)
        s3 = self.V[1] + (spaceObj.h * t2)/2
        tmp = self.copy(self.coord[0] + spaceObj.h /2, self.coord[1] + (spaceObj.h * s3)/ 2)
        t3 = tmp.Vy(args)
        s4 = self.V[1] + (spaceObj.h * t3)
        tmp = self.copy(self.coord[0] + spaceObj.h, self.coord[1] + spaceObj.h * s4)
        t4 = tmp.Vy(args)
        x1 = self.coord[0] + ((spaceObj.h)/6) * (k1 + 2 * k2 + 2 * k3 + k4)
        vx1 = self.V[0] + ((spaceObj.h) / 6) * (l1 + 2 * l2 + 2 * l3 + l4)
        y1 = self.coord[1] + ((spaceObj.h) / 6) * (s1 + 2 * s2 + 2 * s3 + s4)
        vy1 = self.V[1] + ((spaceObj.h) / 6) * (t1 + 2 * t2 + 2 * t3 + t4)
        return [x1,y1,vx1,vy1]
        
    def ae_update(self,i):
        self.data[i][0] = self.coord[0]/spaceObj.ae
        self.data[i][1] = self.V[0]
        self.data[i][2] = self.coord[1]/spaceObj.ae
        self.data[i][3] = self.V[1]
        
    def update(self,tmp):
        self.coord[0] = tmp[0]
        self.coord[1] = tmp[1]
        self.V[0] = tmp[2]
        self.V[1] = tmp[3]

Файл с определением класса и файл с кодом основной программы

from spaceObj import spaceObj
    
N = 20*365
Mercury = spaceObj(328.5*(10**21),[57910000000,0],[0,47870],N)
Venera = spaceObj(4.867*(10**24),[0,108200000000],[35020,0],N)
Earth = spaceObj(5.9726*(10**24),[147098290000,0],[0,29780],N)
Mars = spaceObj(639*(10**21),[2.06655*(10**11),0],[0,24170],N)
Jupiter = spaceObj(1.898*(10**27),[7.405736*(10**11),0],[0,13070],N)
Saturn = spaceObj(568.3*(10**24),[0,1353572956000],[9690,0],N)
Uran = spaceObj(8.6832*(10**25),[2748938461000,0],[0,6810],N)
Neptun = spaceObj(102.4*(10**24),[4452940833000,0],[0,5430],N)
for i in range(N):
    merc_tmp = Mercury.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Uran, Neptun)
    Mercury.ae_update(i)
    ven_tmp = Venera.RKStep(Mercury, Earth, Mars, Jupiter, Saturn, Uran, Neptun)
    Venera.ae_update(i)
    earth_tmp = Earth.RKStep(Venera, Mercury, Mars, Jupiter, Saturn, Uran, Neptun)
    Earth.ae_update(i)
    mars_tmp = Mars.RKStep(Venera, Earth, Mercury, Jupiter, Saturn, Uran, Neptun)
    Mars.ae_update(i)
    jup_tmp = Jupiter.RKStep(Venera, Earth, Mars, Mercury, Saturn, Uran, Neptun)
    Jupiter.ae_update(i)
    sat_tmp = Saturn.RKStep(Venera, Earth, Mars, Jupiter, Mercury, Uran, Neptun)
    Saturn.ae_update(i)
    ur_tmp = Uran.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Mercury, Neptun)
    Uran.ae_update(i)
    nep_tmp = Neptun.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Uran, Mercury)
    Neptun.ae_update(i)
    
    Mercury.update(merc_tmp)
    Venera.update(ven_tmp)
    Earth.update(earth_tmp)
    Mars.update(mars_tmp)
    Jupiter.update(jup_tmp)
    Saturn.update(sat_tmp)
    Uran.update(ur_tmp)
    Neptun.update(nep_tmp)
    
for i in range(N):
    print(Earth.data[i][0],' ',Earth.data[i][1])
Так как он не выдает даже строчку где вылетает эта ошибка, то я вообще не представляю откуда она берется. Вроде бы когда писал код, все было логично и таких ляпов не должно было быть. Помогите, пожалуйста

Единственное что выяснил, циклится на вызове RKStep
terabayt
ElberMendax
И зацикливание работы
он не зацикливается а прост долго работает
сделайте N меньше, например 10
и будет вам результат
или
for i in range(N):
    merc_tmp = Mercury.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Uran, Neptun)
    Mercury.ae_update(i)
    ven_tmp = Venera.RKStep(Mercury, Earth, Mars, Jupiter, Saturn, Uran, Neptun)
    Venera.ae_update(i)
    earth_tmp = Earth.RKStep(Venera, Mercury, Mars, Jupiter, Saturn, Uran, Neptun)
    Earth.ae_update(i)
    mars_tmp = Mars.RKStep(Venera, Earth, Mercury, Jupiter, Saturn, Uran, Neptun)
    Mars.ae_update(i)
    jup_tmp = Jupiter.RKStep(Venera, Earth, Mars, Mercury, Saturn, Uran, Neptun)
    Jupiter.ae_update(i)
    sat_tmp = Saturn.RKStep(Venera, Earth, Mars, Jupiter, Mercury, Uran, Neptun)
    Saturn.ae_update(i)
    ur_tmp = Uran.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Mercury, Neptun)
    Uran.ae_update(i)
    nep_tmp = Neptun.RKStep(Venera, Earth, Mars, Jupiter, Saturn, Uran, Mercury)
    Neptun.ae_update(i)
    
    Mercury.update(merc_tmp)
    Venera.update(ven_tmp)
    Earth.update(earth_tmp)
    Mars.update(mars_tmp)
    Jupiter.update(jup_tmp)
    Saturn.update(sat_tmp)
    Uran.update(ur_tmp)
    Neptun.update(nep_tmp)
    print i
и будет видно что оно работает
ElberMendax
О, и вправду)
Спасибо)
Странно, без добавления ООП все работало быстрее
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB