In python, there have a very clear structure about class, for example like blow.
The self concept is very convenience avoid the duplicate variable.
And it can also write the function to change the variable inside.
class object():
def __init__(self):
self.a
self.b
......
def addoneinside(self):
self.a = a + 1
In R, I need to use <- change the value after return. Maybe I can use %<>% to do this.
But in python, I can do object.addoneinside(), then the object.a will become 2 automatically.
I really like r because the data process is really easy and intuition.
Is this possible to change R code style like python?
Related
I have Pyhton classes A and B. I want to access the value of x in class B.
class A():
def __init__(self):
self.x = 0
def do(self):
self.x = 1 + 2
class B():
#get the value of x which is 3, not 0.
How do I do this? If I create an instance, init is called which re-initializes x to 0, but I want the final value of x which is 3.
Does anyone please have a solution?
Avoiding dependencies between classes is an important principle of OOP which should not be violated lightly. To the extent that classes need to interchange information, this should happen via public and documented methods.
Python doesn't enforce this, but you should probably be looking for a different way to address whichever problem you hope to solve with this arrangement.
The class A doesn't have any x which exists in the class itself; the way you have defined the class, x is an instance attribute. It is only defined when you have an object which belongs to the class, and each object instance has a value for this variable which is separate from every other instance's. The class itself doesn't have a variable with this name.
Perhaps you are really looking for a class attribute, something like this?
class A():
x = None
def __init__(self):
if self.__class__.x is None:
self.__class__.x = 0
def do(self):
self.__class__.x = 3
#classmethod
def _get_x(cls):
return cls.x
class B():
:
value_of_A_x = A._get_x()
The leading underscore in the name of the class method _get_x informally suggests that this is a private method.
You'll notice that x has three states. It starts out as None, then when the first instance of an A object is created, it gets set to 0. The first time an instance's do method is called, it gets set to 3. There are currently no other ways to change its value, though you are of course free to change this code or add new code in accordance with your requirements.
The above is highly speculative, but should at the very least help you write a better question by explaining what you actually want to achieve. Code which doesn't work at all is not a good way to tell us what you actually want.
The following code is a simplified example of a task I'm working on, using Python, that seems to be a natural fit for an OOP style:
class Foo:
def __init__(self):
self.x = 1
self.y = 1
self.z = 1
def method(self):
return bar(self.x,self.y,self.z)
def bar(x,y,z):
return x+y+z
f = Foo()
print(f.method())
In the example code above, I have three instance variables in my object, but in my actual application it would be more like 10 or 15 variables, and if I implement what I have in mind in this style, then I'm going to end up with a lot of code that looks like this:
return bar(self.a.self.b,self.c,self.d,self.e,self.f,self.g,self.h,self.i)
Wow, it sure would be nice to be able to write this in a style more like this:
return bar(a,b,c,d,e,f,g,h,i)
That would be a lot more concise and readable. One way to do this might be to rewrite bar so that it takes a Foo object as an input rather than a bunch of scalar variables, but I would prefer not to do that. Actually, that would just push the syntactic cruft down into the bar function, where I guess I would have code that looked like this:
def bar(f):
return f.a+f.b+f.c
Is there a nicer way to handle this? My understanding is that without the "self.", I would be referencing class variables rather than instance variables. I thought about using a dictionary, but that seems even cruftier, with all the ["a"] stuff. Might there be some automated way to take a dictionary with keys like "a","b","c",... and kind of unload the values into local variables named a, b, c, and so on?
I think you're going about this the wrong way. You're correct that your examples are hard to read, but I don't think the root cause is Python's syntax. An argument list that contains 10-15 variables is going to be difficult to read in any programming languages. I think the problem is your program's structure. Instead of trying to find ways around Python's syntax and conventions, consider trying to refactor your program so your classes don't need so many attributes, or refactor your methods so they don't need to return so many attributes.
Unfortunately I can't help you do that without seeing the full version of your code, but Code Review Stack Exchange would be a good place to get some help with that. Reducing the number of values returned and not coming up with unconventional ways to list and manipulate your attributes will make your code easier to read and maintain, both for others and yourself in the future.
Well, you could do it like so if you really wanted to, but I would advice against it. What if you add a field to your class and so on? Also it just makes things more complicated.
class Foo:
def __init__(self):
self.x = 1
self.y = 1
self.z = 1
def method(self):
return bar(**vars(self)) # expand all attributes as arguments
def bar(x,y,z):
return x+y+z
f = Foo()
print(f.method())
You can use __dict__ to create attributes from data of varying length, and then use classmethod to sum the attributes passed:
import string
class Foo:
def __init__(self, data):
self.__dict__ = dict(zip(string.ascii_lowercase, data))
#classmethod
def bar(cls, instance, vals = []):
return sum(instance.__dict__.values()) if not vals else sum(getattr(instance, i) for i in vals)
f = Foo(range(20))
print(Foo.bar(f))
print(Foo.bar(f, ['a', 'c', 'e', 'k', 'm']))
Output:
190
28
That is a kind of best practices question.
I have a class structure with some methods defined. In some cases I want to override a particular part of a method. First thought on that is splitting my method to more atomic pieces and override related parts like below.
class myTest(object):
def __init__(self):
pass
def myfunc(self):
self._do_atomic_job()
...
...
def _do_atomic_job(self):
print "Hello"
That is a practical-looking way to solve the problem. But since I have too many parameters that is needed to be transferred to and revieced back from _do_atomic_job(), I do not want to pass and retrieve tons of parameters. Other option is setting these parameters as class variables with self.param_var etc but those parameters are used in a small part of the code and using self is not my preferred way of solving this.
Last option I thought is using inner functions. (I know I will have problems in variable scopes but as I said, this is a best practise and just ignore them and think scope and all things about the inner functions are working as expected)
class MyTest2(object):
mytext = ""
def myfunc(self):
def _do_atomic_job():
mytext = "Hello"
_do_atomic_job()
print mytext
Lets assume that works as expected. What I want to do is overriding the inner function _do_atomic_job()
class MyTest3(MyTest2):
def __init__(self):
super(MyTest3, self).__init__()
self.myfunc._do_atomic_job = self._alt_do_atomic_job # Of course this do not work!
def _alt_do_atomic_job(self):
mytext = "Hollla!"
Do what I want to achieve is overriding inherited class' method's inner function _do_atomic_job
Is it possible?
Either factoring _do_atomic_job() into a proper method, or maybe factoring it
into its own class seem like the best approach to take. Overriding an inner
function can't work, because you won't have access to the local variable of the
containing method.
You say that _do_atomic_job() takes a lot of parameters returns lots of values. Maybe you group some of these parameters into reasonable objects:
_do_atomic_job(start_x, start_y, end_x, end_y) # Separate coordinates
_do_atomic_job(start, end) # Better: start/end points
_do_atomic_job(rect) # Even better: rectangle
If you can't do that, and _do_atomic_job() is reasonably self-contained,
you could create helper classes AtomicJobParams and AtomicJobResult.
An example using namedtuples instead of classes:
AtomicJobParams = namedtuple('AtomicJobParams', ['a', 'b', 'c', 'd'])
jobparams = AtomicJobParams(a, b, c, d)
_do_atomic_job(jobparams) # Returns AtomicJobResult
Finally, if the atomic job is self-contained, you can even factor it into its
own class AtomicJob.
class AtomicJob:
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
self._do_atomic_job()
def _do_atomic_job(self):
...
self.result_1 = 42
self.result_2 = 23
self.result_3 = 443
Overall, this seems more like a code factorization problem. Aim for rather lean
classes that delegate work to helpers where appropriate. Follow the single responsibility principle. If values belong together, bundle them up in a value class.
As David Miller (a prominent Linux kernel developer) recently said:
If you write interfaces with more than 4 or 5 function arguments, it's
possible that you and I cannot be friends.
Inner variables are related to where they are defined and not where they are executed. This prints "hello".
class MyTest2(object):
def __init__(self):
localvariable = "hello"
def do_atomic_job():
print localvariable
self.do_atomic_job = do_atomic_job
def myfunc(self):
localvariable = "hollla!"
self.do_atomic_job()
MyTest2().myfunc()
So I can't see any way you could use the local variables without passing them, which is probably the best way to do it.
Note: Passing locals() will get you a dict of the variables, this is considered quite bad style though.
In my code, I generate new python classes at runtime. For some of them, I want to generate the python code, just as if I wrote these classes in a .py file.
Let's say that I created dynamically a class A:
type('A', (), {'bar':True} which is equivalent to the code:
class A(object):
bar=True
What I want is to generate this equivalent code from my dynamic class.
I'm trying to implement a function "generate_A_code"
kls_A = type('A', (), {'bar':True}
kls_A.generate_A_code()
Hope this helps a bit.
Thanks
Generating the Python code from the class object itself is practically impossible. You need to save the instructions for generating the class in another way.
The best way may be having a function to make the class, and importing & calling it in the generated code. So the generated code would look like this:
kwargs = {answer=42, name='foo'}
import class_maker
SomeClass1 = class_maker.make_class(**kwargs)
The other option is generate the Python code you want directly, exec it to make the class, and then save it with the class.
code = '''class MyClass:
pass
'''
the_locals = {}
exec(code, globals(), the_locals)
MyClass = the_locals['MyClass']
MyClass._code = code
As always with exec, be very careful using it. It can run any Python code. Think hard if there's any way to do whatever you need to do in a different way. People will shout at you for using exec. (But even the Python standard library uses it for dynamic classes sometimes.)
You can use compile(), exec() or eval() depending on your exact needs.
Perhaps you could use inspect.getsource:
import inspect
def generate_kls_A(num):
class A(object):
def __init__(self):
self.init = num
return A
kls_A=generate_kls_A(1)
print(inspect.getsource(kls_A))
yields:
class A(object):
def __init__(self):
self.init = num
I am newbie and finding it very hard to grasp the syntax of Class in python. I have a background of C/C++, java and objective C. A very big difference which i am noticing in python is that you don't explicitly declare the "data members" in the class and you just randomly add them? And it leads to quite big confusion.
Let say i have a class
class MyClass:
def __int__(self, a, b):
self.a = a
self.b = b
And then when i initiate the object.
myobject = MyClass(10,10)
And just after some time for some reason i come to know that i need another parameter in this class but i dont wanted to initiate that using constructor because it will be initiated by another function depending on the some particular condition, so in whole mess of code that will be only point that variable actually get birth. is not the case when i will be checking the code while debugging or reviewing it for some other reason it will be confusing?
In short, Yes.
You're right. Python lets you add (and remove!) members from objects at will, at any time. There's nothing special about a constructor that allows it to do anything that other functions can't.
If you want to be sure that all instances of your class have the same members at all times, then by all means assign them all in the constructor, using a sentinel value like None for ones that don't have a meaningful value yet, and avoid adding new members outside the constructor.
It's up to you how you manipulate your objects, and if you want to do that in a static fashion then that's fine, or if you want to take advantage of the ability to add and remove members at arbitrary times, that's fine too. Python itself doesn't impose (m)any rules.
You should really use some . in your text :p
Could you mean:
class MyClass:
def __int__(self, a, b, c=None):
self.a = a
self.b = b
self.c = c
one = MyClass(1,2)
one.c # None
two = MyClass(1,2,3)
two.c # 3
class MyClass:
def __int__(self, a, b):
self.a = a
self.b = b
self.c = None #This line is optional
def set_c(self, c):
self.c = c
Some people prefer to list all the attributes in the __init__. You don't have to, but there are any number of reasons you might choose to.
Maybe it improves your editor's ability to understand your code for highlighting or completion.
Maybe it is just a style that you prefer.