This is just a way to declare a and b as equal to c.
>>> c=2
>>> a=b=c
>>> a
2
>>> b
2
>>> c
2
So you can use as much as you want:
>>> i=7
>>> a=b=c=d=e=f=g=h=i
You can read more in Multiple Assignment from this Python tutorial.
Python allows you to assign a single value to several variables simultaneously. For example:
a = b = c = 1
Here, an integer object is created with the value 1, and all three variables are assigned to the same memory location. You can also assign multiple objects to multiple variables. For example:
a, b, c = 1, 2, "john"
Here, two integer objects with values 1 and 2 are assigned to variables a and b, and one string object with the value "john" is assigned to the variable c.
There is also another fancy thing! You can swap values like this: a,b=b,a:
>>> a=2
>>> b=5
>>> a,b=b,a
>>> a
5
>>> b
2
Answer from fedorqui on Stack OverflowThis is just a way to declare a and b as equal to c.
>>> c=2
>>> a=b=c
>>> a
2
>>> b
2
>>> c
2
So you can use as much as you want:
>>> i=7
>>> a=b=c=d=e=f=g=h=i
You can read more in Multiple Assignment from this Python tutorial.
Python allows you to assign a single value to several variables simultaneously. For example:
a = b = c = 1
Here, an integer object is created with the value 1, and all three variables are assigned to the same memory location. You can also assign multiple objects to multiple variables. For example:
a, b, c = 1, 2, "john"
Here, two integer objects with values 1 and 2 are assigned to variables a and b, and one string object with the value "john" is assigned to the variable c.
There is also another fancy thing! You can swap values like this: a,b=b,a:
>>> a=2
>>> b=5
>>> a,b=b,a
>>> a
5
>>> b
2
python support multi variable assignment at a time called multiassignment.
In [188]: a = b = c = d = 4
In [189]: a
Out[189]: 4
In [190]: b
Out[190]: 4
In [191]: c
Out[191]: 4
In [192]: d
Out[192]: 4
In [193]: a = 2
In [194]: b = 2
is same as for immutable object
In [195]: a, b = 2 #int is a immutable object like `tuple`, `str`
while this is not to be mean for mutable object like list, dictionary
read about mutable and immutable
Videos
This is documented here.
Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
And, as an example,
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
Python chains relational operators "naturally". Note that Python's relational operators include in and is (and their negatives), which can lead to some surprising results when mixing them with the symbolic relational operators.
This is very convenient, but under the hood, is it the same as what we have to do in any other language? As in:
temp=a a = b b = temp
Or is there a reason to think a,b=b,a is actually faster than assigning a temp variable?
I'm doing this on a larger level, something like d,e,b,a,c = a,b,c,d,e which still works but I'm wondering if that's inefficient.
» pip install python-abc
I noticed in a leetcode quesiton answer this -
node.next.random = node.random and node.random.next
Now from my understanding in other languages node.random and node.random.next should return true if both exist and false if they don't, but chatgpt says:
"node.random and node.random.next is an expression using the and logical operator. In Python, the and operator returns the first operand if it is falsy (e.g., None, False, 0, or ""); otherwise, it returns the second operand"
I don't understand this.
I am being asked to maintain code that subclasses from abc.ABC. I have read the python documentation, the associated PEP, and even visited pymotw. I do not understand what abstract classes give you.
If I have class A and then I derive subclass B from it wouldn't issubclass(B,A) still be true?
In a, b = b, a + b, the expressions on the right hand side are evaluated before being assigned to the left hand side. So it is equivalent to:
c = a + b
a = b
b = c
In the second example, the value of a has already been changed by the time b = a + b is run. Hence, the result is different.
The line:
a, b = b, a + b
is closer to:
temp_a = a
a = b
b = temp_a + b
where b is using the old value of a before a was reassigned to the value of b.
Python first evaluates the right-hand expression and stores the results on the stack, then takes those two values and assigns them to a and b. That means that a + b is calculated before a is changed.
See How does swapping of members in the python tuples (a,b)=(b,a) work internally? for the low-down on how this all works, at the bytecode level.
SubQuery is an abstract base class (per the abc module) with one or more abstract methods that you did not override. By adding ABC to the list of base classes, you defined ValueSum itself to be an abstract base class. That means you aren't forced to override the methods, but it also means you cannot instantiate ValueSum itself.
PyCharm is warning you ahead of time that you need to implement the abstract methods inherited from SubQuery; if you don't, you would get an error from Python when you actually tried to instantiate ValueSum.
As to what inheriting from ABC does, the answer is... not much. It's a convenience for setting the metaclass. The following are equivalent:
class Foo(metaclass=abc.ABCMeta):
...
and
class Foo(abc.ABC):
...
The metaclass modifies __new__ so that every attempt to create an instance of your class checks that the class has implemented all methods decorated with @abstractmethod in a parent class.
The 'Abstract Base classes" or abc.ABC is a helper class
https://docs.python.org/3/library/abc.html
Here's a snippet of why they exist:
The collections module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition, the
collections.abcsubmodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, if it is hashable or if it is a mapping.
A good example here: https://pymotw.com/2/abc/ | https://pymotw.com/3/abc/
From pymotw:
Forgetting to set the metaclass properly means the concrete implementations do not have their APIs enforced. To make it easier to set up the abstract class properly, a base class is provided that sets the metaclass automatically.
abc_abc_base.py
import abc
class PluginBase(abc.ABC):
@abc.abstractmethod
def load(self, input):
"""Retrieve data from the input source
and return an object.
"""
@abc.abstractmethod
def save(self, output, data):
"""Save the data object to the output."""
class SubclassImplementation(PluginBase):
def load(self, input):
return input.read()
def save(self, output, data):
return output.write(data)
if __name__ == '__main__':
print('Subclass:', issubclass(SubclassImplementation,
PluginBase))
print('Instance:', isinstance(SubclassImplementation(),
PluginBase))
There are no pointers to variables in Python. In particular, when you say this:
Is the statement replacing the pointer
c -> awith pointerc -> b...
Python does not have any such thing as "the pointer c -> a", so it is not doing that.
...or grabbing the value from b and overwriting a with b's value
but there is no assignment to a, so it's not doing that either.
Instead, Python keeps a symbol table1 that maps each name (a, b, c, etc.) to a pointer to an object. In your code sample, after you assign to a and b, it would look like this (obviously I have made up the memory addresses):
a -> 0xfffa9600 -> 1
b -> 0xfffa9608 -> 2
and then after you assign c = a, it would look like this:
a -> 0xfffa9600 -> 1
b -> 0xfffa9608 -> 2
c -> 0xfffa9600 -> 1
Note that c is entirely independent of a. When you run c = b, it replaces the pointer associated with c in the symbol table with the pointer that was associated with b, but a is not affected:
a -> 0xfffa9600 -> 1
b -> 0xfffa9608 -> 2
c -> 0xfffa9608 -> 2
In this case that's pretty much all there is to it because the objects in question, namely the integer constants 1 and 2, are immutable. However, if you use mutable objects, they do start to act a bit more like pointers in the sense that changes to the object when it's stored in one variable are reflected in other variables that refer to the same object. For example, consider this sample of code:
x = {'a': 1, 'b': 2}
y = x
Here, the symbol table might look something like this:
x -> 0xffdc1040 -> {'a': 1, 'b': 2}
y -> 0xffdc1040 -> {'a': 1, 'b': 2}
If you now run
y['b'] = y['a']
then it doesn't actually change the pointer associated with y in the symbol table, but it does change the object pointed to by that pointer, so you wind up with
x -> 0xffdc1040 -> {'a': 1, 'b': 1}
y -> 0xffdc1040 -> {'a': 1, 'b': 1}
and you'll see that your assignment to y['b'] has affected x as well. Contrast this with
y = {'a': 1, 'b': 2}
which actually makes y point at an entirely different object, and is more akin to what you were doing before with a, b, and c.
1Actually there are several symbol tables, corresponding to different scopes, and Python has an order in which it checks them, but that detail isn't particularly relevant here.
c doesn't "Point at a or b"... it points at the 1 or 2 objects.
>>> a = 1
>>> b = 2
>>> c = a
>>> c
1
>>> c = b
>>> c
2
>>> b = 3
>>> c
2
This can be proven somewhat with id() - b and c point at the same "thing":
>>> b = 2
>>> c = b
>>> id(b)
42766656
>>> id(c)
42766656
s.accept() returns a tuple of two values : (host, port).
Therefore,
conn, address = s.accept()
is (apart that accept() is called twice) the same as
conn, address = s.accept()[0], s.accept()[1]
when receiving a tuple you can unpack(or "split") it into its members by using this syntax:
member1, member2, member3 = tuple
or
member1, member2 member3 = (member1, member2 member3)
in your case you are receiving a tuple of the form (connection, address), so to unpack it into two variables you write:
conn, address = s.accept()
It's equivalent to this:
returned_tuple = s.accept()
conn, address = returned_tuple