Reputation: 975
I am certain I am doing this "incorrectly" even though it works. Right now when I call a function I just pass the whole object i.e.
class my_file_obj:
def __init__(self,filename):
self.filename = filename
self.owner = None
self.file_type = None
self.fileflag = 0
self.md5 = None
The function call, where file_obj1
is an instance of my_file_obj
:
some_function(file_obj1)
and then referencing the attributes I need as needed within the function.
What is the "python"/correct way of doing this?
some_function(file_obj1)
some_function(file_obj1.filename)
the_filename = file_obj1.filename
some_function(the_filename)
Upvotes: 3
Views: 1595
Reputation: 12920
Or you may add a def __str__(self): return self.filename
method to your class (because, maybe, printing a file object should return its name in your design anyways) and accept any kind of object for your function. The function then, for example, looks like this:
def openFile(obj):
return open(str(obj), 'rU')
Like this, the function accepts both strings and objects of your class. See http://en.wikipedia.org/wiki/Duck_typing.
Not sure if this design is recommended -- just want to point out something less obvious. Maybe this is even pythonic?
Upvotes: 0
Reputation: 51797
Well, it depends on what you want to do and what your goal is.
If you have a function that looks something like this:
def some_function(file_thingy):
with open(file_thingy.filename, 'w') as f:
f.write("Icky Icky Icky Patang NeeeeWom!")
Then it makes things much more generic - as long as you pass an object in that has a .filename
attribute that is a string then your function will work. A more common example of this is when people talk about duck typing. If it looks like a duck, walks like a duck, and quacks like a duck, well then it's a duck!
So if you have the following function:
def do_duck_things(a_duck):
print(a_duck.appearance)
a_duck.waddle()
a_duck.quack()
print("It must be a duck!")
Then you could pass it an instance of:
class Duck:
def __init__(self):
self.appearance = "White, like the AFLAC duck"
def quack(self):
print("Quaaaaaack!")
def waddle(self):
print("The duck waddles.")
or an instance of either of these classes:
class UglyDuckling:
def __init__(self):
self.appearance = "Suspiciously like a baby goose"
def waddle(self):
print("The ugly duckling waddles a bit like a duck.")
def quack(self):
print("Hoooonk!")
class Human:
def __init__(self):
self.appearance = "Looks like a human in a duck costume"
def waddle(self):
print("Surprisingly, he waddles quite like a duck.")
def quack(self):
print("<A sound quite like Donald Duck would make>")
So in your case, it really depends on what your function should be doing. If all it's doing is reading the contents of a file, then you can (and probably should) just send it a filename. But if you want to do something like, say, check the file against your stored MD5, or set that MD5, then it's perfectly appropriate to pass in the object.
HTH
Upvotes: 0
Reputation: 4916
All the ways are acceptable and which you will choose will depend on your application (or design) choices.
# with this call the file_obj1 object reference is sent to some_function()
some_function(file_obj1)
# with this call there is no pass by reference. If filename is a
# string it is copied to some_function
some_function(file_obj1.filename)
# same as before, but here you are allocating a new var and copying the content
# to some_function
the_filename = file_obj1.filename
some_function(the_filename)
Upvotes: 1
Reputation: 176
I think some_function(file_obj1)
is the most pythonic.
some_function(file_obj1.filename)
doesn't pass the object to the function, it only passes the filename attribute as a string. It then would require a lot of fiddly code to get the rest of the object's attributes.
Upvotes: 1
Reputation: 129764
Well, it's quite obvious. It depends on whether some_function
needs the whole object or just the filename, in which case you pass the whole my_file_obj
instance or just the filename.
Upvotes: 5