在另一个对象中传递对象的属性和方法
Passing attributes and methods of object inside another object
我正在 Python 3.9 中写一个 API。我将首先提供一个简化的示例,说明我正在处理的内容,下面的代码将从设计的角度对我试图实现的内容进行一些扩展。我刚刚开始涉足更复杂的设计和对象组合的事情,所以我尝试做的一些事情完全有可能是不可能的或不是最佳实践——我很想知道我可以改进什么。
在primary_module.py
中:
from some_module import do_something
from secondary_module import SecondaryClass
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(PrimaryClass)
sec_cls.secondary_method()
在secondary_module.py
中:
class SecondaryClass:
def secondary_method(pri_cls):
print(pri_cls.attr1)
print(pri_cls._attr2)
如您所见,我在 secondary_module.py
中定义了一个 class SecondaryClass
并使用它在 primary_module.py
。从 API 的角度来看,我希望最终用户只能直接访问 PrimaryClass
,永远不要让他们看到 SecondaryClass
,即使它是在幕后使用的。唯一需要实例化 SecondaryClass
的时间是 运行ning PrimaryClass.primary_method()
和相关对象,因此没有 SecondaryClass
会 运行 作为独立对象的情况.但是,当运行使用此方法时,SecondaryClass
需要访问PrimaryClass
中包含的一些用户指定的数据。请记住 SecondaryClass
(理论上)永远不会被最终用户直接访问,允许 SecondaryClass
查看 PrimaryClass
的某些属性的最佳方法是什么?在 SecondaryClass.secondary_method()
的定义中使用 duck typing 来授予它访问 PrimaryClass
的某些属性(public 和隐藏)的权限是否可以接受?或者有没有我没有想到的更好的解决方案?
不是很清楚,但我想这就是你想要的:
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(self)
sec_cls.secondary_method()
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, primary):
self.primary = primary
def secondary_method():
print(self.primary.attr1)
print(self.primary._attr2)
要对 primary_module
的用户隐藏 SecondaryClass
,请使用:
from secondary_module import SecondaryClass as _SecondaryClass
见Hide external modules when importing a module (e.g. regarding code-completion)
如果不了解 classes 实际在做什么,就很难讨论这个问题。
就是说,让两个 class 相互依赖通常不是一个好主意,因为这往往会生成脆弱的代码: class 中的任何一个的变化都可能破坏 classes 以及任何依赖它们的人。
最好明确地传递 secondary_method
它需要的东西(即 secondary_method(self._attr2)
),可能作为函数指针(例如 lambda: __private_method()
、lambda: self.attr1
),通过 class 构造函数(即 __init__
)或作为 secondary_method
的方法参数。这样,SecondaryClass
就不会具体依赖于 PrimaryClass
,并且 secondary_method
和 SecondaryClass
的依赖性是明确的。
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
# E.g. 1: Pass _attr2 via constructor
sec_cls = SecondaryClass(self._attr2)
# E.g. 2+3: Pass attr1 and _attr2 as method parameters
sec_cls.secondary_method(
lambda: self.attr1,
lambda: __private_method(),
)
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, attr2):
self.attr2 = attr2
def secondary_method(get_attr1, private_callback):
print(self.attr2) # <- _attr2, received from constructor
print(get_attr1()) # <- Getting attr1 at execution time from lambda
private_callback() # <- Calling __private_method
我正在 Python 3.9 中写一个 API。我将首先提供一个简化的示例,说明我正在处理的内容,下面的代码将从设计的角度对我试图实现的内容进行一些扩展。我刚刚开始涉足更复杂的设计和对象组合的事情,所以我尝试做的一些事情完全有可能是不可能的或不是最佳实践——我很想知道我可以改进什么。
在primary_module.py
中:
from some_module import do_something
from secondary_module import SecondaryClass
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(PrimaryClass)
sec_cls.secondary_method()
在secondary_module.py
中:
class SecondaryClass:
def secondary_method(pri_cls):
print(pri_cls.attr1)
print(pri_cls._attr2)
如您所见,我在 secondary_module.py
中定义了一个 class SecondaryClass
并使用它在 primary_module.py
。从 API 的角度来看,我希望最终用户只能直接访问 PrimaryClass
,永远不要让他们看到 SecondaryClass
,即使它是在幕后使用的。唯一需要实例化 SecondaryClass
的时间是 运行ning PrimaryClass.primary_method()
和相关对象,因此没有 SecondaryClass
会 运行 作为独立对象的情况.但是,当运行使用此方法时,SecondaryClass
需要访问PrimaryClass
中包含的一些用户指定的数据。请记住 SecondaryClass
(理论上)永远不会被最终用户直接访问,允许 SecondaryClass
查看 PrimaryClass
的某些属性的最佳方法是什么?在 SecondaryClass.secondary_method()
的定义中使用 duck typing 来授予它访问 PrimaryClass
的某些属性(public 和隐藏)的权限是否可以接受?或者有没有我没有想到的更好的解决方案?
不是很清楚,但我想这就是你想要的:
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(self)
sec_cls.secondary_method()
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, primary):
self.primary = primary
def secondary_method():
print(self.primary.attr1)
print(self.primary._attr2)
要对 primary_module
的用户隐藏 SecondaryClass
,请使用:
from secondary_module import SecondaryClass as _SecondaryClass
见Hide external modules when importing a module (e.g. regarding code-completion)
如果不了解 classes 实际在做什么,就很难讨论这个问题。
就是说,让两个 class 相互依赖通常不是一个好主意,因为这往往会生成脆弱的代码: class 中的任何一个的变化都可能破坏 classes 以及任何依赖它们的人。
最好明确地传递 secondary_method
它需要的东西(即 secondary_method(self._attr2)
),可能作为函数指针(例如 lambda: __private_method()
、lambda: self.attr1
),通过 class 构造函数(即 __init__
)或作为 secondary_method
的方法参数。这样,SecondaryClass
就不会具体依赖于 PrimaryClass
,并且 secondary_method
和 SecondaryClass
的依赖性是明确的。
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
# E.g. 1: Pass _attr2 via constructor
sec_cls = SecondaryClass(self._attr2)
# E.g. 2+3: Pass attr1 and _attr2 as method parameters
sec_cls.secondary_method(
lambda: self.attr1,
lambda: __private_method(),
)
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, attr2):
self.attr2 = attr2
def secondary_method(get_attr1, private_callback):
print(self.attr2) # <- _attr2, received from constructor
print(get_attr1()) # <- Getting attr1 at execution time from lambda
private_callback() # <- Calling __private_method