Object References, Mutability, and Recycling
Posted neozheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Object References, Mutability, and Recycling相关的知识,希望对你有一定的参考价值。
1. Function Parameters as References
The only mode of parameter passing in Python is call by sharing(共享传参). Call by sharing means that each formal parameter of the function gets a copy of each reference in the arguments. In other words, the parameters inside the function become aliases of the actual arguments.
The result of this scheme is that a function may change any mutable object passed as a parameters, but it cannot change the identity of those objects.
Example 8-11. A function may change any mutable object it receives.
"""A function may change any mutable object it receives""" >>> def f(a, b): ... a += b ... return a ... >>> x = 1 >>> y = 2 >>> f(x, y) 3 >>> x, y # The number x is unchanged. (1, 2) >>> >>> a = [1, 2] >>> b = [3, 4] >>> f(a, b) [1, 2, 3, 4] >>> a, b # The list a is changed. ([1, 2, 3, 4], [3, 4]) >>> >>> >>> t = (10, 20) >>> u = (30, 40) >>> f(t, u) (10, 20, 30, 40) >>> t, u # The tuple t is unchanged. ((10, 20), (30, 40)) >>>
Python 函数传参参考:https://www.cnblogs.com/zhoug2020/p/9110663.html
2. Mutable Types as Parameter Defaults: Bad idea
You should avoid mutable objects as default values for parameters.
EXample 8-12. A simple class to illustrate the danger of a mutable default.
class HauntedBus: def __init__(self, passengers=[]): # When the passengers argument is not given, this parameter is bound to the default list object, which is initially empty. self.passengers = passengers # This assignment makes self.passenger an alias for passengers, which is itself an alias for the default list, when no passengers argument is given. def pick(self, name): self.passengers.append(name) # When the methods .remove() and .append() are used with self.passengers, we are actually mutating the default list, which is an attribute of the function object. def drop(self, name): self.passengers.remove(name) # Example 8-13 shows the eerie behavior of the HauntedBus """ >>> bus1 = HauntedBus([‘Alice‘, ‘Bill‘]) >>> bus1.passengers [‘Alice‘, ‘Bill‘] >>> bus1.pick(‘Charlie‘) >>> bus1.drop(‘Alice‘) >>> bus1.passengers # bus1 正常运行 [‘Bill‘, ‘Charlie‘] >>> >>> bus2 = HauntedBus() # bus2 starts empty, so the default empty list is assigned to self.passengers. >>> bus2.pick(‘Carrie‘) >>> bus2.passengers [‘Carrie‘] >>> >>> bus3 = HauntedBus() # bus3 also starts empty, again the default list is assigned. >>> bus3.passengers # The default is no longer empty! [‘Carrie‘] >>> bus3.pick(‘Dave‘) >>> bus2.passengers # Now Dave, picked by bus3, appears in bus2. [‘Carrie‘, ‘Dave‘] >>> >>> bus2.passengers is bus3.passengers # bus2.passengers and bus3.passengers refer to the same list. True >>> bus1.passengers # But bus1.passengers is a distinct list. [‘Bill‘, ‘Charlie‘] """ # The problem is that Bus instances that don‘t get an initial passenger list end up sharing the same passenger list among themselves. """ Strange things happen only when a HauntedBus starts empty, because then self.passengers becomes am alias for the default value of the passengers parameter. The problem is that each default value is evaluated when the function is defined -- i.e., usually when the module is loaded -- and the default values become attributes of the function object. So if a default value is a mutable object, and you change it, the change will affect every future call of the function. """ # Inspect the HauntedBus.__init__ object and see the students haunting its __defaults__ attribute: """ >>> dir(HauntedBus.__init__) [‘__annotations__‘, ‘__call__‘, ‘__class__‘, ‘__closure__‘, ‘__code__‘, ‘__defaults__‘, ‘__delattr__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__get__‘, ‘__getattribute__‘, ‘__globals__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘, ‘__kwdefaults__‘, ‘__le__‘, ‘__lt__‘, ‘__module__‘, ‘__name__‘, ‘__ne__‘, ‘__new__‘, ‘__qualname__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘] >>> HauntedBus.__init__.__defaults__ ([‘Carrie‘, ‘Dave‘],) >>> """ # Finally, we can verify that bus2.passengers is an alias bound to the first element of the HauntedBus.__init__.__defaults__ attributes: """ >>> HauntedBus.__init__.__defaults__[0] is bus2.passengers True """ # The issue with mutable defaults explains why None is often used as the default value for parameters that may receive # mutable values.
end...
以上是关于Object References, Mutability, and Recycling的主要内容,如果未能解决你的问题,请参考以下文章
object references an unsaved transient instance
object references an unsaved transient instance异常
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService") 上的错误;
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient i
ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [object references
object references an unsaved transient instance - save the transient instance before flushing: com.j