【问题标题】:Set class attribute after inheritance继承后设置类属性
【发布时间】:2019-03-09 14:07:24
【问题描述】:

是否可以这样做:

class ParentClassName(object):
    name = camel_case_to_underscore(cls.__name__)

class ChildClassName(Parent):
    pass

assert Parent().name == "parent_class_name" 
assert Child().name == "child_class_name" 
assert Child.name == "child_class_name" 
assert getattr(Child, 'name') == "child_class_name" 

我想创建一个类,其他类可以从该类继承并根据它们的类名设置它们的名称。 在 python 3 中可以吗?

【问题讨论】:

  • 已经存在的cls.__name__ 属性有什么问题?
  • cf 我编辑的答案

标签: python inheritance metaprogramming


【解决方案1】:

是的,类也是对象,因此您可以设置属性,就像在常规对象中一样。

但是,它是 Child.name,而不是 Child().nameChild() 创建一个实例,并将 name 分配给该实例,而不是类。

【讨论】:

  • 但问题是我想根据类名返回值
  • 在你声明类之后,输入类似ChildClassName.name = ChildClassName.__name__ + 'something else'
【解决方案2】:

你不需要它,它已经在那里了:

>>> class Parent(): pass
... 
>>> class Child(): pass
... 
>>> Parent.__name__
'Parent'
>>> Child.__name__
'Child'
>>> 

但是,如果您真的坚持自己滚动,无论出于何种原因您没有费心解释,您可以使用自定义元类:

def camel_case_to_underscore(name):
    # your code here

class NamedType(type):
    def __new__(meta, name, bases, attribs):
        attribs["name"] = camel_case_to_underscore(name)
        return type.__new__(meta, name, bases, attribs)

class Parent(metaclass=NamedType):
    pass

class Child(Parent):
    pass

【讨论】:

  • 但我想做的是修改名称
  • “修改名称”是什么意思?我强烈怀疑这里有一个 XY 问题 (en.wikipedia.org/wiki/XY_problem),所以你最好解释一下你真正想用这个实现什么(你想用这个功能解决哪个问题)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
相关资源
最近更新 更多