如何使用 class 方法创建自定义 class 实例?
How can I use a class method to create a custom class instance?
我是 Python OOP 的新手,正在尝试创建一个 class 我可以根据是否要自定义实例以这两种方式生成实例:
alien_one = Alien(1)
alien_two = Alien(1).customize(anger=5, emotion=1)
在弄乱了 class 方法和静态方法之后,我得到了以下代码,我觉得根据其他线程我应该使用它们:
class Alien(object):
def __init__(self, polarity):
self.polarity = {1 : 'friendly', 2 : 'aggressive'}
def customize(self, **kwargs):
for event in kwargs:
# // process events to change self.polarity
return self
这段代码是否适合创建 Alien 的实例,或者我应该使用方法装饰器来生成实例?在我开始之前,有些事情让我感觉很糟糕。
编辑:感谢大家的回复,普遍的共识是将任何表达式或 kwargs 传递给 __init__
。我提到的一些示例代码如下所示:
query = Tweet.update(is_published=True).where(Tweet.creation_date < today)
这是取自 Peewee ORM 的示例。当我尝试在我的 class 中使用方法装饰器 (static/class) 时,我丢失了 is_published
参数并且无法访问它。为了更清楚地理解,任何人都可以解释 is_published
和 Tweet.creation_date
是如何在 class 对象中被接收的,看起来查询是推文 [=31] 的全新实例=].我只是以 Peewee 为例来了解这段代码是如何工作的,而不是试图弄清楚 Peewee 本身的任何细节是如何工作的。
据推测,您这样做是为了在创建后改变您的实例。如果是这种情况,请考虑重组您的代码以实现不变性,因为有 very real advantages in many situations。如果您不进行变异,请采纳@katy lavallee 的建议并将其移至 __init__.
您可以使用构建的 setattr 以编程方式设置实例上的字段:
for key, val in kwargs.items():
setattr(self, key, val)
如果这是 python 2(如果是这样,请进行切换)您需要将对 items() 的调用替换为 iteritems()。
我觉得首先要定义哪些属性应该是内部的,哪些属性应该暴露给接口。例如,您可能希望极性是内部属性,取决于愤怒。
class Alien(object):
polarity = 1
polarity_names = {1 : 'friendly', 2 : 'aggressive'}
def __init__(self, anger=1):
self.customize(
anger = anger,
)
def get_polarity(self):
return self.polarity_names[self.polarity]
def customize(self, **kwargs):
for feeling_name, feeling_intensity in kwargs.items():
if feeling_name == 'anger':
self.polarity = feeling_intensity
alien_one = Alien()
print('Alien 1 polarity: ' + alien_one.get_polarity())
alien_two = Alien(anger=2)
print('Alien 2 polarity: ' + alien_two.get_polarity())
我是 Python OOP 的新手,正在尝试创建一个 class 我可以根据是否要自定义实例以这两种方式生成实例:
alien_one = Alien(1)
alien_two = Alien(1).customize(anger=5, emotion=1)
在弄乱了 class 方法和静态方法之后,我得到了以下代码,我觉得根据其他线程我应该使用它们:
class Alien(object):
def __init__(self, polarity):
self.polarity = {1 : 'friendly', 2 : 'aggressive'}
def customize(self, **kwargs):
for event in kwargs:
# // process events to change self.polarity
return self
这段代码是否适合创建 Alien 的实例,或者我应该使用方法装饰器来生成实例?在我开始之前,有些事情让我感觉很糟糕。
编辑:感谢大家的回复,普遍的共识是将任何表达式或 kwargs 传递给 __init__
。我提到的一些示例代码如下所示:
query = Tweet.update(is_published=True).where(Tweet.creation_date < today)
这是取自 Peewee ORM 的示例。当我尝试在我的 class 中使用方法装饰器 (static/class) 时,我丢失了 is_published
参数并且无法访问它。为了更清楚地理解,任何人都可以解释 is_published
和 Tweet.creation_date
是如何在 class 对象中被接收的,看起来查询是推文 [=31] 的全新实例=].我只是以 Peewee 为例来了解这段代码是如何工作的,而不是试图弄清楚 Peewee 本身的任何细节是如何工作的。
据推测,您这样做是为了在创建后改变您的实例。如果是这种情况,请考虑重组您的代码以实现不变性,因为有 very real advantages in many situations。如果您不进行变异,请采纳@katy lavallee 的建议并将其移至 __init__.
您可以使用构建的 setattr 以编程方式设置实例上的字段:
for key, val in kwargs.items():
setattr(self, key, val)
如果这是 python 2(如果是这样,请进行切换)您需要将对 items() 的调用替换为 iteritems()。
我觉得首先要定义哪些属性应该是内部的,哪些属性应该暴露给接口。例如,您可能希望极性是内部属性,取决于愤怒。
class Alien(object):
polarity = 1
polarity_names = {1 : 'friendly', 2 : 'aggressive'}
def __init__(self, anger=1):
self.customize(
anger = anger,
)
def get_polarity(self):
return self.polarity_names[self.polarity]
def customize(self, **kwargs):
for feeling_name, feeling_intensity in kwargs.items():
if feeling_name == 'anger':
self.polarity = feeling_intensity
alien_one = Alien()
print('Alien 1 polarity: ' + alien_one.get_polarity())
alien_two = Alien(anger=2)
print('Alien 2 polarity: ' + alien_two.get_polarity())