Malzemeler arasında yineleme yapılırken düğüm özelliğinin Yok olup olmadığı nasıl kontrol edilir?

Aug 17 2020

Bazı harman dosyalarında düğümler ve düğüm grupları arasında yineleme yaparken öznitelik yok hatasıyla karşılaşıyorum.

Hata: AttributeError: 'NoneType' nesnesinin 'name' özniteliği yok

Nesnelerin 'ad' özelliği olup olmadığını nasıl kontrol edebilirim ve atlayabilirim?

   for mat in bpy.data.materials:
        if mat.use_nodes == True:
            for node in mat.node_tree.nodes:
                #check if no has attribute name
                if node.type in ["GROUP"] and node.node_tree.name == 'NodeGroupName':

Yanıtlar

3 batFINGER Aug 17 2020 at 17:41

Bir öznitelik olabilir None

Hata NoneType has no attribute, blender komut dosyası oluşturmada görülen yaygın bir hatadır. Örneğin şu durumda olabilir:context.object is None

OP, bu hata mesajını daha iyi yansıtacak şekilde soru başlığının düzenlenmesini tavsiye eder.

Error: AttributeError: 'NoneType' object has no attribute 'name'

tarafından atılan node.node_tree.name == 'NodeGroupName'bilgi node.node_treedeğerine sahiptir None. Durum böyle olup olmadığını test edebilir, yani

if node.node_tree is  None:

aksine

if hasattr(node, "node_tree"):

Düğüm ağacı olduğunda her ikisi de doğru olacaktır None

Bir grup düğümünün nasıl ekleneceğinin (henüz) farkında olmadığım ve bağlantılı düğüm ağacına sahip olmadığım için, söz konusu kodun bu hatayı atması aslında garip bir durum. Bunun, bpy.data.node_groupsbir malzeme düğüm ağacının düğümü olan bir düğüm grubunu silmenin sonucu olduğunu varsayalım ..

dolayısıyla soru komut dosyasının son satırı

if (node.type in ["GROUP"]  
        and node.node_tree 
        and node.node_tree.name == 'NodeGroupName'
        ):

zincirleme ve ilk önce durduğundan beri False

Kullanma getattr

Hemen hemen üçüncü argüman öntanımlı olarak get özniteliğini kullanarak aynı şeyi ele alacağımızdan

node_tree = getattr(node, "node_tree", None)

her Noneiki durumda da olacaktır. IMO bu, düğüm ağacının her ikisini de kullanarak "üstün gelir" ve ardından ad öznitelik testine sahiptir. NoneBiz 's hiçbiri gereksiz görünüyor özellikler için daha fazla test biliyorsanız, ilgisi de bir düğüm ağacı değilse emin misin Noneo bir ada sahip olur .bpy.types.ShaderNodeTree.name

Test komut dosyası

Yukarıdakini bir düğüm 'GROUP'türü için "çift test" ile kullanmak, düğüm olmayan bir ağacı olup olmadığını kontrol edin.

Malzeme adı, düğüm adı demetlerinin bir listesini içeren düğüm grubu adıyla eşleşen anahtarlarla bir sözlük oluşturun.

import bpy
from bpy import data
from collections import defaultdict

# all the group nodes in blendfile
print(data.node_groups.keys())
    
group_nodes = defaultdict(list)
# create a look up dictionary 
for m in data.materials:
    if m.use_nodes:
        for n in m.node_tree.nodes:
            nt = getattr(n, "node_tree", None)
            if nt and n.type == 'GROUP':
                group_nodes[nt.name].append((m.name, n.name))
                
print(group_nodes) 

Çıktı.

1 düğüm grubu "Test_Material", 2 malzeme "TestMat" ve "TestMat.001" dosyası.

Düğüm grubu her iki malzemede de "Grup" adıyla kullanılır.

['Test_Material']

defaultdict(<class 'list'>, {'Test_Material': [('TestMat', 'Group'), ('TestMat.001', 'Group')]})

Notlar:

Equating dikkat Trueveya Falsetestlerde. Varsayılan olarak python, çoğu türü True veya false ile eşitler. Bazı false örnekleri None, tamsayı 0ve boş bir listedir.[]

hasattrYa Trueda dönüş gibi yöntemlerFalse

if hasattr(foo, "bar") == True:

eğer foo.barvarsa, bu biraz benzer okur

if True == True:

bunun yerine sadece kullan

if hasattr(foo, "bar"):

Düğümün node_tree özniteliği olmadığında boolean false döndürmek yerine boolean false döndürmek için biraz yukarıyı değiştirmek if nt:, her iki durumda da yanlış olacaktır, ancak ikisini ayırt edebiliriz.

        nt = getattr(n, "node_tree", False)
        if nt and n.type == 'GROUP':
            group_nodes[nt.name].append((m.name, n.name))
        if nt is None:
            print(f"{m.name}:{n.name} node_tree is None")
0451 Aug 17 2020 at 04:14

Ron Jensens yorumuna göre:

    for mat in bpy.data.materials:
        if mat.use_nodes == True:
            for node in mat.node_tree.nodes:
                if hasattr(node, 'node_tree') == True:
                    if hasattr(node.node_tree, 'name') == True:
                        if node.type in ["GROUP"] and node.node_tree.name == 'NodeGroupName':