在以下代码中,我希望元类NameMeta
将属性gender
添加到MyName
类,以防该类未声明该属性。
class NameMeta(type):
def __new__(cls, name, bases, dic):
if 'gender' not in dic:
setattr(name, 'gender', 'Male')
return super().__new__(cls, name, bases, dic)
class MyName(metaclass=NameMeta):
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
def fullname(self):
self.full_name = self.fname + self.lname
return self.full_name
inst = MyName('Joseph ', 'Vincent')
print(MyName.gender)
这是我得到的输出:
<ipython-input-111-550ff3cfae41> in __new__(cls, name, bases, dic)
2 def __new__(cls, name, bases, dic):
3 if 'gender' not in dic:
----> 4 setattr(name, 'gender', 'Male')
5 return super().__new__(cls, name, bases, dic)
6
AttributeError: 'str' object has no attribute 'gender'
我知道这个错误是有道理的,因为name
是一个字符串。
我的问题是,如何在元类中访问MyName
类作为对象,以便我可以添加属性?
答案 0 :(得分:3)
你很亲密。您的问题是您尝试使用name
(一个字符串)将您的属性添加到元类的名称。您需要将属性分配给您正在创建的类对象。这可以使用dic
:
class NameMeta(type):
def __new__(cls, name, bases, dic):
if 'gender' not in dic:
dic['gender'] = 'Male'
return super().__new__(cls, name, bases, dic)
通过上述更改,您的代码输出:
Male
答案 1 :(得分:2)
如果它不存在,您可以将它添加到dic
,因为它包含类的属性:
def __new__(mcs, name, bases, dict):
if 'gender' not in dict:
dict['gender'] = 'Male'
# or just `dict.setdefault('gender', 'Male')`
return super().__new__(mcs, name, bases, dic)
# Or you can create the class and set it
cls = super().__new__(mcs, name, bases, dic)
if not hasattr(cls, 'gender'):
cls.gender = 'Male'
return cls
或者你可以有一个类属性:
class NameMeta(type):
gender = 'Male'
# `gender = 'Male'` will be inherited by all classes
# but not instances of those classes.