Python - #property vs func() [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
It had always been my dream to use someclass.func instead of someclass.func(). I read about the #decorators. And now I ask:
Which way is better?
Way 1
class Main(object):
def __init__(self):
self.func()
def func(self):
print 'hi'
or...
Way 2
class Main(object):
def __init__(self):
self.func
#property
def func(self):
print 'hi'
EDIT
Here is the code:
http://randomgalaxy.com/stackoverflow/python-property-vs-func/term.py

If func really prints values, then no, making it a property is not the right thing to do. Properties are—as the name suggest—values that are attached to the object. As such, a function with the #property decorator should only return a value and have otherwise no side-effects.

Edit: after reading your actual code DEFINITELY Way 1
Most likely: Way 1
BUT it depends on what you're actually trying to do. This case you presented is way oversimplified.
Using the #property decorator is in my experience either a way to protect a class member (only allowing reads), A way to do some bookkeeping when a variable is set/read, or a way to provide access to a member-like function (ie, just returns a value you request even if it requires some extra computation to get that value). I personally like to use it for lazy evaluation

Properties should be values. Not functions.
Example:
class Foo(object):
def __init__(self, a, b):
self.__a = a
self.__b = b
#property
def a(self):
return self.__a
#property
def b(self):
return self.__b
In this example, values are private and you can't change them.
So it's a bad idea to do something else there? I mean in my script function changes my vars and calls another functions – Vik2015 45 secs ago
It's very bad style. You're not in ruby :)

Related

Which of these is the best practice for accessing a variable in a class? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
If I have an object, and within that object I've defined a variable, which of these methods would be considered 'best' for accessing the variable?
Method One
Using a getter function
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
def get_the_variable(self):
return self.the_variable
if __name__ == "__main__"
a = MyClass()
print(a.get_the_variable())
Method Two
Using the #property decorator
class MyClass:
def __init__(self):
self._the_variable = 21 * 2
#property
def the_variable(self):
return self._the_variable
if __name__ == "__main__"
a = MyClass()
print(a.the_variable)
Method Three
Simply accessing it directly
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
if __name__ == "__main__"
a = MyClass()
print(a.the_variable)
Are any of these methods more pythonic than the others?
Method 3 is the standard pythonic way to start. If you need additional logic, filtering or some other behavior for the attribute you can always go back and add a method for the attribute and use the #property decorator at a later time. That's the beauty of python, start with something simple that works. If you later need finer control over the attribute you can create the property and not have to update/change any of the client code that uses the attribute. The client code will not know the difference between accessing the attribute directly vs calling a method and as a result does not have to change.
This ideology is confirmed via PEP 549
Python's descriptor protocol guides programmers towards elegant API design. If your class supports a data-like member, and you might someday need to run code when changing the member's value, you're encouraged to simply declare it as a simple data member of the class for now. If in the future you do need to run code, you can change it to a "property", and happily the API doesn't change.
I think it's not easy to answer since it's based on the program.
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
def get_the_variable(self):
return self.the_variable
But if you want to pass a class attirubete to some variable, I think it's better to use getter-setter, since it is more readable and understandable. Because you are basically telling I ask this value. For example:
if __name__ == "__main__":
a = MyClass()
modified_variable = a.get_the_variable() * 2
In contrary, if you are just using that class attribute, third option a.the_variable is better.
if a.get_the_variable() == 42:
# do something
else:
# do something

(Python) Should I use parameters or make it global? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have many functions that all share the same parameter. They will be inputting and outputting this parameter many times.
For example:
a = foo
a = fun(a)
a = bar(a)
def fun(a):
...
return a
def bar(a):
...
return a
What is more pro-grammatically correct, passing parameters through a function, or having it be globally accessible for all the functions to work with?
a = foo
fun()
bar()
def fun():
global a
...
def bar():
global a
...
The more localised your variables, the better.
This is virtually an axiom for any programming language.
structs in C (and equivalents in other languages such as FORTRAN) grew up from this realisation, and object orientated programming followed shortly after.
For re-usability of method, passing parameter is better way.
I agree with the other answers but just for the sake of completion, as others have pointed out a class sounds like a good idea here. Consider the following.
class myClass(object):
def __init__(self, foo):
self.a = foo
def fun(self):
# do stuff to self.a
def bar(self):
# do something else to self.a
c = myClass(foo)
c.fun()
c.bar()

Idiomatic way of processing instances of derived classes?

Although, I have some years of experience programming in Python every time I encounter a problem like this I'm using the built-in isinstance function. However, I'm not sure whether this is the ideomatic way of doing these kind of things in python.
So, I have a base class that most of my instances will be.
class Base():
def a(self):
return 1
I also have a slightly different class that look like this:
class Extended(Base):
def b(self):
return 2
Now, there is a third class that might have additional functionality depending on the received argument which would be instance of one of the previous classes.
class User():
def __init__(self, arg):
... # do some common work
if isinstance(arg, Extended):
...
# define more functionality which will call method 'b'
# at some point during runtime (as event handler or smth)
Is this really the way to go with Python on this trivial example or maybe I should consider changing the interface of the Base to something like:
class Base2():
supports_more_func = False
def a(self):
return 1
def b(self):
pass
class Extended2(Base2):
supports_more_func = True
def b(self):
return 2
class User():
def __init__(self, arg):
... # do some common work
if arg.supports_more_func:
...
# define more functionality which will call method 'b'
# at some point during runtime (as event handler or smth)
Which one is the better approach according to you guy and why?
Generally speaking, when doing object oriented programming, using isinstance is rarely the way to go, especially when you're in charge of designing the classes you use, because that would be breaking S.O.L.I.D. principles.
Instead you should simply design your class to have a common well defined interface and just use it. So testing for type or for a member is rarely the way to go.
The way I'd go would be:
class Base2():
def a(self):
return 1
def b(self):
pass
class Extended2(Base2):
def b(self):
# all that extra functionality that was in User.__init__()
return 2
class User():
def __init__(self, arg):
... # do some common work
arg.b()
now I guess that the part with:
# define more functionality which will call method 'b'
# at some point during runtime (as event handler or smth)
has some data and processing tightly coupled with User and not with Extended2, but I'm pretty sure there's an elegant way to give that data to arg.b() as argument.
Basically, I'd say that 99% of the time when you need to use isinstance() to do something, it means you have a design issue and there's a better way to do the same.
Here's some web-litterature on the topic:
http://canonical.org/~kragen/isinstance/
https://www.quora.com/When-is-it-acceptable-to-use-isinstance-in-Python
https://www.lynda.com/Programming-Languages-tutorials/Avoiding-isinstance/471978/502199-4.html

Return self in python [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a class that represents object. And I have a bunch of methods which modify this object state with no obvious return or obviously without any return. In C# I would declare all these methods as void and see no alternatives. But in Python I am about to make all the methods return self to give myself ability to write awesome one-liners like this:
classname().method1().method2().method3()
Is this Pythonic, or otherwise acceptable in Python?
Here is a mail from Guido van Rossum (the author of the Python programming language) about this topic: https://mail.python.org/pipermail/python-dev/2003-October/038855.html
I'd like to explain once more why I'm so adamant that sort() shouldn't
return 'self'.
This comes from a coding style (popular in various other languages, I
believe especially Lisp revels in it) where a series of side effects
on a single object can be chained like this:
x.compress().chop(y).sort(z)
which would be the same as
x.compress() x.chop(y) x.sort(z)
I find the chaining form a threat to readability; it requires that the
reader must be intimately familiar with each of the methods. The
second form makes it clear that each of these calls acts on the same
object, and so even if you don't know the class and its methods very
well, you can understand that the second and third call are applied to
x (and that all calls are made for their side-effects), and not to
something else.
I'd like to reserve chaining for operations that return new values,
like string processing operations:
y = x.rstrip("\n").split(":").lower()
There are a few standard library modules that encourage chaining of
side-effect calls (pstat comes to mind). There shouldn't be any new
ones; pstat slipped through my filter when it was weak.
It is an excellent idea for APIs where you are building state through methods. SQLAlchemy uses this to great effect for example:
>>> from sqlalchemy.orm import aliased
>>> adalias1 = aliased(Address)
>>> adalias2 = aliased(Address)
>>> for username, email1, email2 in \
... session.query(User.name, adalias1.email_address, adalias2.email_address).\
... join(adalias1, User.addresses).\
... join(adalias2, User.addresses).\
... filter(adalias1.email_address=='jack#google.com').\
... filter(adalias2.email_address=='j25#yahoo.com'):
... print(username, email1, email2)
Note that it doesn't return self in many cases; it will return a clone of the current object with a certain aspect altered. This way you can create divergent chains based of a shared base; base = instance.method1().method2(), then foo = base.method3() and bar = base.method4().
In the above example, the Query object returned by a Query.join() or Query.filter() call is not the same instance, but a new instance with the filter or join applied to it.
It uses a Generative base class to build upon; so rather than return self, the pattern used is:
def method(self):
clone = self._generate()
clone.foo = 'bar'
return clone
which SQLAlchemy further simplified by using a decorator:
def _generative(func):
#wraps(func)
def decorator(self, *args, **kw):
new_self = self._generate()
func(new_self, *args, **kw)
return new_self
return decorator
class FooBar(GenerativeBase):
#_generative
def method(self):
self.foo = 'bar'
All the #_generative-decorated method has to do is make the alterations on the copy, the decorator takes care of producing the copy, binding the method to the copy rather than the original, and returning it to the caller for you.
Here is an example which demonstrates a scenario when it may be a good technique
class A:
def __init__(self, x):
self.x = x
def add(self, y):
self.x += y
return self
def multiply(self, y):
self.x *= y
return self
def get(self):
return self.x
a = A(0)
print a.add(5).mulitply(2).get()
In this case you are able to create an object in which the order in which operations are performed are strictly determined by the order of the function call, which might make the code more readable (but also longer).
If you so desire, you can use a decorator here. It will stand out to someone looking through your code to see the interface, and you don't have to explicitly return self from every function (which could be annoying if you have multiple exit points).
import functools
def fluent(func):
#functools.wraps(func)
def wrapped(*args, **kwargs):
# Assume it's a method.
self = args[0]
func(*args, **kwargs)
return self
return wrapped
class Foo(object):
#fluent
def bar(self):
print("bar")
#fluent
def baz(self, value):
print("baz: {}".format(value))
foo = Foo()
foo.bar().baz(10)
Prints:
bar
baz: 10

how to return a function in a different class in python 3.3 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I know this is a really bad description but how can i get this to work:
class Test1():
def test_p1():
print("This is part 1 of Test1")
def Test2():
return test_p1()
Thanks in advance!
Well, there are several options.
The most basic are:
Create instance first
class Test1():
def test_p1(self):
print("This is part 1 of Test1")
def Test2():
return Test1().test_p1()
However, you should use it when having new instance makes sense (depends on your API).
Make it class method
class Test1():
#classmethod
def test_p1(cls):
print("This is part 1 of Test1")
def Test2():
return Test1.test_p1()
Make it static method (discouraged)
class Test1():
#staticmethod
def test_p1():
print("This is part 1 of Test1")
def Test2():
return Test1.test_p1()
Alternative: use inheritance
In some cases (maybe it is your case too, we do not know) it makes sense to actually utilize inheritance: create a class that will inherit from Test1. This way you can override parts of it and refer to parent methods. Example:
class Test1():
def test_p1(self):
print("This is part 1 of Test1")
class SomeOtherClass(Test1):
def test2(self):
return super(SomeOtherClass, self).test_p1()
and then use it like this:
my_instance = SomeOtherClass()
result = my_instance.test2()
But again, it really depends on your API / library.
Alternative 2: module-level function
User #user2357112 correctly pointed out, that module-level function can be even better (simpler) idea:
def test_p1():
print("This is part 1 of Test1")
def Test2():
return test_p1()
Side note: PEP8
To avoid confusion, as Python is really dynamic, you should give a "hint" to developers on what they are using, and in general follow coding style defined in PEP8:
module names are all_lower_case,
functions and methods are also all_lower_case,
classes are CamelCase (same applies to factory-like functions returning class instances),
constants are ALL_UPPER_CASE,
object properies are all_lower_case,
(and many more - the above is only about non-confusing naming)
Tadeck gave a detailed answer while I was typing mine, but here is my initial solution to what I believe you are trying to accomplish. I'm adding my input simply because I'm new to Python and I think a beginner's perspective may be beneficial for OP.
class Test1():
def test_p1(self):
print "This is part 1 of Test1"
def Test2():
myTest = Test1()
return myTest.test_p1()
Test2()
In your original code you attempt to call the test_p1 method without ever instantiating the Test1 class. So I did that first, myTest = Test1(), and then called the test_p1() method using my newly created myTest object.
Also, I added self to the argument list in the test_p1 method. I don't exactly understand why but apparently the lack of self makes it an unbound method which causes some problems.
You have to specify the class containing the functin. Call Test1.test_p1().
(Works in python3, but not in 2.x as there is this fuzz about bound and unbound thingies.)
Maybe you would want to use capital letters for classes and minuscules for functions.
A more common case is the following:
You have a class that defines methods:
class Animal:
def bark (self): print ('woof')
Then somewhere else you instantiate an object of this class and then invoke the method of the instance:
spike = Animal ()
spike.bark ()

Categories

Resources