class problem, NoneType obj has no attribute

G

globalrev

wassup here?

7

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 22, in
<module>
print cust1.getID()
AttributeError: 'NoneType' object has no attribute 'getID'


class customer:
def __init__(self, ID, movies):
self.ID = ID
self.movies = movies

def getID():
return self.ID

def getMovies():
return self.movies


import os
import customer
import movie

mv1 = open('C:\\Python25\\myPrograms\\netflix\\mv1exp2.txt', 'r+')
mv1str = mv1.read()

print mv1str.count(',5,')

cust1 = customer.__init__('12',['1','435','2332'])
print cust1.getID()
 
B

Bruno Desthuilliers

globalrev a écrit :
wassup here?


7

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 22, in
<module>
print cust1.getID()
AttributeError: 'NoneType' object has no attribute 'getID'



class customer:

1/ naming convention : class names should be CamelCased
2/ unless you need compatibility with years old Python versions, use
newstyle classes

class Customer(object):
def __init__(self, ID, movies):
self.ID = ID
self.movies = movies

3/ naming conventions : ALL_UPPER_NAMES denote (pseudo) constants

def __init__(self, id, movies):
self.id = id
self.movies = movies
def getID():
return self.ID

def getMovies():
return self.movies

4/ Python has support for computed attributes, so you just don't need
these getters.
import os
import customer
import movie

mv1 = open('C:\\Python25\\myPrograms\\netflix\\mv1exp2.txt', 'r+')
mv1str = mv1.read()

print mv1str.count(',5,')

cust1 = customer.__init__('12',['1','435','2332'])

__init__ is automagically called on instanciation, so you don't have to
call it yourself. And FWIW, your __init__ returns None.

cust1 = Customer('12', ['1', '435', '2332'])
print cust1.getID()

print cust1.id
 
G

globalrev

globalrev a écrit :
wassup here?

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 22, in
<module>
print cust1.getID()
AttributeError: 'NoneType' object has no attribute 'getID'
class customer:

1/ naming convention : class names should be CamelCased
2/ unless you need compatibility with years old Python versions, use
newstyle classes

class Customer(object):
def __init__(self, ID, movies):
self.ID = ID
self.movies = movies

3/ naming conventions : ALL_UPPER_NAMES denote (pseudo) constants

def __init__(self, id, movies):
self.id = id
self.movies = movies
def getID():
return self.ID
def getMovies():
return self.movies

4/ Python has support for computed attributes, so you just don't need
these getters.


import os
import customer
import movie
mv1 = open('C:\\Python25\\myPrograms\\netflix\\mv1exp2.txt', 'r+')
mv1str = mv1.read()
print mv1str.count(',5,')
cust1 = customer.__init__('12',['1','435','2332'])

__init__ is automagically called on instanciation, so you don't have to
call it yourself. And FWIW, your __init__ returns None.

cust1 = Customer('12', ['1', '435', '2332'])
print cust1.getID()

print cust1.id


what should init return normally? a customer-object?

class customer:
def __init__(self, idnbr, movies):
self.idnbr = idnbr
self.movies = movies
return self


?
 
G

globalrev

globalrev a écrit :
wassup here?

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 22, in
<module>
print cust1.getID()
AttributeError: 'NoneType' object has no attribute 'getID'
class customer:

1/ naming convention : class names should be CamelCased
2/ unless you need compatibility with years old Python versions, use
newstyle classes

class Customer(object):
def __init__(self, ID, movies):
self.ID = ID
self.movies = movies

3/ naming conventions : ALL_UPPER_NAMES denote (pseudo) constants

def __init__(self, id, movies):
self.id = id
self.movies = movies
def getID():
return self.ID
def getMovies():
return self.movies

4/ Python has support for computed attributes, so you just don't need
these getters.


import os
import customer
import movie
mv1 = open('C:\\Python25\\myPrograms\\netflix\\mv1exp2.txt', 'r+')
mv1str = mv1.read()
print mv1str.count(',5,')
cust1 = customer.__init__('12',['1','435','2332'])

__init__ is automagically called on instanciation, so you don't have to
call it yourself. And FWIW, your __init__ returns None.

cust1 = Customer('12', ['1', '435', '2332'])
print cust1.getID()

print cust1.id

print "cust", cust1.idnbr, cust1.movies()

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 24, in
<module>
print "cust", cust1.idnbr, cust1.movies()
TypeError: 'list' object is not callable

when class =
class customer:
def __init__(self, idnbr, movies):
self.idnbr = idnbr
self.movies = movies

print "cust", cust1.idnbr, cust1.movies()

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 24, in
<module>
print "cust", cust1.idnbr, cust1.movies()
TypeError: 'list' object is not callable

when class =
class customer:
def __init__(self, idnbr, movies):
self.idnbr = idnbr
self.movies = movies
 
P

Peter Otten

globalrev said:
Christian said:
globalrev schrieb:
cust1 = customer.__init__('12',['1','435','2332'])
cust1 = customer('12',['1','435','2332'])

... and before that

from customer import customer

Peter

why do i have to write that?

if i do import customer im importing everything no?

but youre right it doesnt work unless i do, i just dont get why.

It becomes clearer if you follow the usual naming conventions and start the
class name with an uppercase letter:


# in file customer.py

class Customer:
# your code

The import then becomes

from customer import Customer

i. e. the first "customer" denotes the module, the second "Customer" the
class.

Peter
 
J

J. Cliff Dyer

globalrev a écrit :
wassup here?

Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 22, in
<module>
print cust1.getID()
AttributeError: 'NoneType' object has no attribute 'getID'
class customer:

1/ naming convention : class names should be CamelCased
2/ unless you need compatibility with years old Python versions, use
newstyle classes

class Customer(object):
def __init__(self, ID, movies):
self.ID = ID
self.movies = movies

3/ naming conventions : ALL_UPPER_NAMES denote (pseudo) constants

def __init__(self, id, movies):
self.id = id
self.movies = movies
def getID():
return self.ID
def getMovies():
return self.movies

4/ Python has support for computed attributes, so you just don't need
these getters.


import os
import customer
import movie
mv1 = open('C:\\Python25\\myPrograms\\netflix\\mv1exp2.txt', 'r+')
mv1str = mv1.read()
print mv1str.count(',5,')
cust1 = customer.__init__('12',['1','435','2332'])

__init__ is automagically called on instanciation, so you don't have to
call it yourself. And FWIW, your __init__ returns None.

cust1 = Customer('12', ['1', '435', '2332'])
print cust1.getID()

print cust1.id


what should init return normally? a customer-object?

class customer:
def __init__(self, idnbr, movies):
self.idnbr = idnbr
self.movies = movies
return self


?

No. __init__ should not return anything (rather, it should return None,
but it'll do that on its own without you telling it to return anything).
The problem is that you are trying to create an object with __init__,
but that is not what it does. It *initializes* objects that already
exist. when you call a class, it creates a new instance using
__new__(), and then initializes it using __init__(). So if you were
really inclined to muck around. You could do something like

cust1 = Customer.__new__(Customer)
cust1.__init__('12', ['1','435', '2332'])

But that would just be silly. What you really want is this:

cust1 = Customer('12', ['1','435', '2332'])

which does the same thing. Don't explicitly call under-under variables
unless you really have to.

Cheers,
Cliff
 
B

Bruno Desthuilliers

globalrev a écrit :
globalrev a écrit : (snip)
cust1 = customer.__init__('12',['1','435','2332'])
__init__ is automagically called on instanciation, so you don't have to
call it yourself. And FWIW, your __init__ returns None.

what should init return normally?

None. Your __init__ is fine, the problem is with the call. To
instanciate a class, you call the class object itself, passing it the
arguments awaited by __init__, ie:


cust1 = Customer('12', ['1', '435', '2332'])
 
B

Bruno Desthuilliers

globalrev a écrit :
> when class =
> class customer:

Please, do yourself and the world a favour, follow naming conventions
(not only will this make your code more readable, but also quite a lot
of things in Python rely on conventions).

And really, use newstyle classes unless you have a *very* compelling
reason not to.

class Customer(object):
> def __init__(self, idnbr, movies):
> self.idnbr = idnbr
> self.movies = movies
>
print "cust", cust1.idnbr, cust1.movies()

Why do you want to call a list ???
Traceback (most recent call last):
File "C:\Python25\myPrograms\netflix\netflix.py", line 24, in
<module>
print "cust", cust1.idnbr, cust1.movies()
TypeError: 'list' object is not callable

Indeed. cust1.movie being a list, that's just what you would expect.
Hint : what do you think will happen with the following code:

alist = [1, 2, 3]
alist()

When I say that Python has support for computed attributes, it doesn't
mean it will automagically add getters/setters for your attributes, but
that by default you just *don't need* getters/setters - you'll be able
to transparently add them latter if there's an effective need for them -
where "transparently" means "without client code knowing it's in fact
calling a getter or setter".

Example:

# before:
class Foo(object):
def __init__(self, name):
# just a plain attribute assignment
self.name = name

f = Foo('bruno')
# just a plain attribute access
print f.name

# after
class Foo(object):
def __init__(self, name):
# still looks like a plain attribute assignment
self.name = name

# defining the setter and getter
def _setname(self, name):
print "setting %s name to '%s'" % (self, name)
self._name = name
def _getname(self):
print "retrieving %s name ('%s')" % (self, self._name)
return self._name.upper()

# and making this a computed attribute using the getter and
# setter under the hood
name = property(fget=_getname, fset=_setname)

f = Foo('bruno')
# still looks like a plain attribute access
print f.name

Also, given your recent posts here, I strongly suggest you take some
time doing at least the official tutorial.

HTH
 
J

J. Cliff Dyer

Christian said:
globalrev schrieb:
cust1 = customer.__init__('12',['1','435','2332'])
cust1 = customer('12',['1','435','2332'])

... and before that

from customer import customer

Peter

why do i have to write that?

if i do import customer im importing everything no?

Not exactly. That's how perl and PHP tend to do it, but python's import
system is much more conservative (and far superior because of it). When
you import a name you get that name and nothing else. You can still
call your class without doing from customer import customer, but you
have to include the module in the class name like this:

cust1 = customer.customer('12',['1','435','2332'])

Everything stays hidden behind the name customer. That way, if customer
defines a class that has the same name that you already have in your
namespace, it won't get overwritten. Say you define a class Purchase in
your customer module, and then in the interpreter, you write

py>>> import customer
py>>> Purchase = 4
py>>> bread = customer.Purchase('bread')
py>>> Purchase
4
py>>> bread
<customer.Purchase object at 0xabcdefab>
py>>>

Purchase and customer.Purchase can live happily side by side. In perl
or PHP, the default behavior causes errors which are hard to debug
because you can't see what names are being pulled into your namespace.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top